diff --git a/.github/workflows/windows_clang.yml b/.github/workflows/windows_clang.yml new file mode 100644 index 0000000000..cbf0a8c8a6 --- /dev/null +++ b/.github/workflows/windows_clang.yml @@ -0,0 +1,32 @@ +name: Windows + +on: [push, pull_request] + +jobs: + clang9: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v1 + - name: install Clang + run: curl -fsSL -o LLVM9.exe https://releases.llvm.org/9.0.0/LLVM-9.0.0-win64.exe ; 7z x LLVM9.exe -y -o"C:/Program Files/LLVM" + - name: cmake + run: cmake -S . -B build -DCMAKE_CXX_COMPILER="C:/Program Files/LLVM/bin/clang++.exe" -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On + - name: build + run: cmake --build build --parallel 10 + - name: test + run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure + + clang10: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v1 + - name: install Clang + run: curl -fsSL -o LLVM10.exe https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/LLVM-10.0.0-win64.exe ; 7z x LLVM10.exe -y -o"C:/Program Files/LLVM" + - name: cmake + run: cmake -S . -B build -DCMAKE_CXX_COMPILER="C:/Program Files/LLVM/bin/clang++.exe" -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On + - name: build + run: cmake --build build --parallel 10 + - name: test + run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure diff --git a/.github/workflows/windows_clang_cl.yml b/.github/workflows/windows_clang_cl.yml new file mode 100644 index 0000000000..4b5a5f5acf --- /dev/null +++ b/.github/workflows/windows_clang_cl.yml @@ -0,0 +1,30 @@ +name: Windows + +on: [push, pull_request] + +jobs: + clang-cl-10-x64: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v1 + - name: cmake + run: cmake -S . -B build -G "Visual Studio 16 2019" -A x64 -T ClangCL -DJSON_BuildTests=On + - name: build + run: cmake --build build --config Debug --parallel 10 + - name: test + run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure + + clang-cl-10-x86: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v1 + - name: cmake + run: cmake -S . -B build -G "Visual Studio 16 2019" -A Win32 -T ClangCL -DJSON_BuildTests=On + - name: build + run: cmake --build build --config Debug --parallel 10 + - name: test + run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure diff --git a/.travis.yml b/.travis.yml index 0fef3f44b8..ef6c24b5c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,17 +10,6 @@ sudo: required group: edge -################### -# global settings # -################### - -env: - global: - # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created - # via the "travis encrypt" command using the project repo's public key - - secure: "m89SSgE+ASLO38rSKx7MTXK3n5NkP9bIx95jwY71YEiuFzib30PDJ/DifKnXxBjvy/AkCGztErQRk/8ZCvq+4HXozU2knEGnL/RUitvlwbhzfh2D4lmS3BvWBGS3N3NewoPBrRmdcvnT0xjOGXxtZaJ3P74TkB9GBnlz/HmKORA=" - - ################ # build matrix # ################ @@ -129,6 +118,9 @@ matrix: env: - SPECIAL=coverity - COMPILER=clang++-3.6 + # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created + # via the "travis encrypt" command using the project repo's public key + - secure: "m89SSgE+ASLO38rSKx7MTXK3n5NkP9bIx95jwY71YEiuFzib30PDJ/DifKnXxBjvy/AkCGztErQRk/8ZCvq+4HXozU2knEGnL/RUitvlwbhzfh2D4lmS3BvWBGS3N3NewoPBrRmdcvnT0xjOGXxtZaJ3P74TkB9GBnlz/HmKORA=" # OSX / Clang @@ -150,6 +142,9 @@ matrix: - os: osx osx_image: xcode11.2 + - os: osx + osx_image: xcode12 + # Linux / GCC - os: linux diff --git a/CMakeLists.txt b/CMakeLists.txt index 372a7a03aa..5df3f99f90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.1) ## PROJECT ## name and version ## -project(nlohmann_json VERSION 3.8.0 DESCRIPTION "JSON for Modern C++" LANGUAGES CXX) +project(nlohmann_json VERSION 3.8.0 LANGUAGES CXX) ## ## INCLUDE diff --git a/Makefile b/Makefile index 3d296baf97..fd73a33892 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ ########################################################################## # directory to recent compiler binaries -COMPILER_DIR=/Users/niels/Documents/projects/compilers/local/bin +COMPILER_DIR=/usr/local/opt/llvm/bin # find GNU sed to use `-i` parameter SED:=$(shell command -v gsed || which sed) @@ -30,7 +30,6 @@ AMALGAMATED_FILE=single_include/nlohmann/json.hpp all: @echo "amalgamate - amalgamate file single_include/nlohmann/json.hpp from the include/nlohmann sources" @echo "ChangeLog.md - generate ChangeLog file" - @echo "check - compile and execute test suite" @echo "check-amalgamation - check whether sources have been amalgamated" @echo "clean - remove built files" @echo "coverage - create coverage information with lcov" @@ -44,26 +43,12 @@ all: @echo "fuzz_testing_cbor - prepare fuzz testing of the CBOR parser" @echo "fuzz_testing_msgpack - prepare fuzz testing of the MessagePack parser" @echo "fuzz_testing_ubjson - prepare fuzz testing of the UBJSON parser" - @echo "json_unit - create single-file test executable" @echo "pedantic_clang - run Clang with maximal warning flags" @echo "pedantic_gcc - run GCC with maximal warning flags" @echo "pretty - beautify code with Artistic Style" @echo "run_benchmarks - build and run benchmarks" -########################################################################## -# unit tests -########################################################################## - -# build unit tests -json_unit: - @$(MAKE) json_unit -C test - -# run unit tests -check: - $(MAKE) check -C test - - ########################################################################## # coverage ########################################################################## @@ -484,13 +469,13 @@ cpplint: # call Clang-Tidy clang_tidy: - $(COMPILER_DIR)/clang-tidy $(AMALGAMATED_FILE) -- -Iinclude -std=c++11 + $(COMPILER_DIR)/clang-tidy $(SRCS) -- -Iinclude -std=c++11 # call PVS-Studio Analyzer pvs_studio: rm -fr pvs_studio_build mkdir pvs_studio_build - cd pvs_studio_build ; cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=On + cd pvs_studio_build ; cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DJSON_MultipleHeaders=ON cd pvs_studio_build ; pvs-studio-analyzer analyze -j 10 cd pvs_studio_build ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs open pvs_studio_build/pvs/index.html @@ -499,7 +484,7 @@ pvs_studio: infer: rm -fr infer_build mkdir infer_build - cd infer_build ; infer compile -- cmake .. ; infer run -- make -j 4 + cd infer_build ; infer compile -- cmake .. -DJSON_MultipleHeaders=ON ; infer run -- make -j 4 # call OCLint static analyzer oclint: @@ -562,7 +547,7 @@ check-amalgamation: check-single-includes: @for x in $(SRCS); do \ echo "Checking self-sufficiency of $$x..." ; \ - echo "#include <$$x>\nint main() {}\n" | sed 's|include/||' > single_include_test.cpp; \ + echo "#include <$$x>\nint main() {}\n" | $(SED) 's|include/||' > single_include_test.cpp; \ $(CXX) $(CXXFLAGS) -Iinclude -std=c++11 single_include_test.cpp -o single_include_test; \ rm -f single_include_test.cpp single_include_test; \ done @@ -572,17 +557,17 @@ check-single-includes: # CMake ########################################################################## -# grep "^option" CMakeLists.txt test/CMakeLists.txt | sed 's/(/ /' | awk '{print $2}' | xargs +# grep "^option" CMakeLists.txt test/CMakeLists.txt | $(SED) 's/(/ /' | awk '{print $2}' | xargs # check if all flags of our CMake files work check_cmake_flags_do: $(CMAKE_BINARY) --version - for flag in '' JSON_BuildTests JSON_Install JSON_MultipleHeaders JSON_Sanitizer JSON_Valgrind JSON_NoExceptions JSON_Coverage; do \ + for flag in JSON_BuildTests JSON_Install JSON_MultipleHeaders JSON_Sanitizer JSON_Valgrind JSON_NoExceptions JSON_Coverage; do \ rm -fr cmake_build; \ mkdir cmake_build; \ - echo "$(CMAKE_BINARY) .. -D$$flag=On" ; \ + echo "\n\n$(CMAKE_BINARY) .. -D$$flag=On\n" ; \ cd cmake_build ; \ - CXX=g++-8 $(CMAKE_BINARY) .. -D$$flag=On -DCMAKE_CXX_COMPILE_FEATURES="cxx_std_11;cxx_range_for" -DCMAKE_CXX_FLAGS="-std=gnu++11" ; \ + $(CMAKE_BINARY) -Werror=dev .. -D$$flag=On -DCMAKE_CXX_COMPILE_FEATURES="cxx_std_11;cxx_range_for" -DCMAKE_CXX_FLAGS="-std=gnu++11" ; \ test -f Makefile || exit 1 ; \ cd .. ; \ done; @@ -642,7 +627,6 @@ clean: rm -fr cmake-3.1.0-Darwin64.tar.gz cmake-3.1.0-Darwin64 rm -fr build_coverage build_benchmarks fuzz-testing clang_analyze_build pvs_studio_build infer_build clang_sanitize_build cmake_build $(MAKE) clean -Cdoc - $(MAKE) clean -Ctest ########################################################################## # Thirdparty code @@ -651,6 +635,6 @@ clean: update_hedley: rm -f include/nlohmann/thirdparty/hedley/hedley.hpp include/nlohmann/thirdparty/hedley/hedley_undef.hpp curl https://raw.githubusercontent.com/nemequ/hedley/master/hedley.h -o include/nlohmann/thirdparty/hedley/hedley.hpp - gsed -i 's/HEDLEY_/JSON_HEDLEY_/g' include/nlohmann/thirdparty/hedley/hedley.hpp - grep "[[:blank:]]*#[[:blank:]]*undef" include/nlohmann/thirdparty/hedley/hedley.hpp | grep -v "__" | sort | uniq | gsed 's/ //g' | gsed 's/undef/undef /g' > include/nlohmann/thirdparty/hedley/hedley_undef.hpp + $(SED) -i 's/HEDLEY_/JSON_HEDLEY_/g' include/nlohmann/thirdparty/hedley/hedley.hpp + grep "[[:blank:]]*#[[:blank:]]*undef" include/nlohmann/thirdparty/hedley/hedley.hpp | grep -v "__" | sort | uniq | $(SED) 's/ //g' | $(SED) 's/undef/undef /g' > include/nlohmann/thirdparty/hedley/hedley_undef.hpp $(MAKE) amalgamate diff --git a/README.md b/README.md index 15b63bc834..c1463349e9 100644 --- a/README.md +++ b/README.md @@ -483,7 +483,7 @@ MyIterator begin(MyContainer& tgt) { } MyIterator end(const MyContainer&) { - return {}; + return {}; } void foo() { @@ -761,7 +761,7 @@ j_document.merge_patch(j_patch); Supported types can be implicitly converted to JSON values. It is recommended to **NOT USE** implicit conversions **FROM** a JSON value. -You can find more details about this recommendation [here](https://www.github.com/nlohmann/json/issues/958). +You can find more details about this recommendation [here](https://www.github.com/nlohmann/json/issues/958). ```cpp // strings @@ -914,7 +914,7 @@ namespace ns { std::string street; int housenumber; int postcode; - + public: NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode) }; @@ -1190,6 +1190,7 @@ Though it's 2020 already, the support for C++11 is still a bit sparse. Currently - GCC 4.8 - 10.1 (and possibly later) - Clang 3.4 - 10.0 (and possibly later) +- Apple Clang 9.1 - 12.0 (and possibly later) - Intel C++ Compiler 17.0.2 (and possibly later) - Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later) - Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later) @@ -1225,6 +1226,7 @@ The following compilers are currently used in continuous integration at [Travis] | Apple Clang 10.0.1 (clang-1001.0.46.4); Xcode 10.2.1 | macOS 10.14.4 | Travis | | Apple Clang 11.0.0 (clang-1100.0.33.12); Xcode 11.2.1 | macOS 10.14.6 | Travis | | Apple Clang 11.0.3 (clang-1103.0.32.59); Xcode 11.4.1 | macOS 10.15.4 | GitHub Actions | +| Apple Clang 12.0.0 (clang-1200.0.22.7); Xcode 11.4.1 | macOS 10.15.5 | Travis | | Clang 3.5.0 (3.5.0-4ubuntu2~trusty2) | Ubuntu 14.04.5 LTS | Travis | | Clang 3.6.2 (3.6.2-svn240577-1~exp1) | Ubuntu 14.04.5 LTS | Travis | | Clang 3.7.1 (3.7.1-svn253571-1~exp1) | Ubuntu 14.04.5 LTS | Travis | @@ -1235,6 +1237,8 @@ The following compilers are currently used in continuous integration at [Travis] | Clang 6.0.1 (6.0.1-svn334776-1~exp1~20190309042707.121) | Ubuntu 14.04.5 LTS | Travis | | Clang 7.1.0 (7.1.0-svn353565-1~exp1~20190419134007.64) | Ubuntu 14.04.5 LTS | Travis | | Clang 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) | Ubuntu 18.04.4 LTS | Travis | +| Clang 9.0.0 (x86_64-pc-windows-msvc) | Windows-10.0.17763 | GitHub Actions | +| Clang 10.0.0 (x86_64-pc-windows-msvc) | Windows-10.0.17763 | GitHub Actions | | GCC 4.8.5 (Ubuntu 4.8.5-4ubuntu8~14.04.2) | Ubuntu 14.04.5 LTS | Travis | | GCC 4.9.4 (Ubuntu 4.9.4-2ubuntu1~14.04.1) | Ubuntu 14.04.5 LTS | Travis | | GCC 5.5.0 (Ubuntu 5.5.0-12ubuntu1~14.04) | Ubuntu 14.04.5 LTS | Travis | @@ -1250,6 +1254,7 @@ The following compilers are currently used in continuous integration at [Travis] | MSVC 19.16.27035.0 (15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | AppVeyor | | MSVC 19.25.28614.0 (Build Engine version 16.5.0+d4cbfca49 for .NET Framework) | Windows-10.0.17763 | AppVeyor | | MSVC 19.25.28614.0 (Build Engine version 16.5.0+d4cbfca49 for .NET Framework) | Windows-10.0.17763 | GitHub Actions | +| MSVC 19.25.28614.0 (Build Engine version 16.5.0+d4cbfca49 for .NET Framework) with ClangCL 10.0.0 | Windows-10.0.17763 | GitHub Actions | ## License @@ -1564,7 +1569,7 @@ This library does not support comments by default. It does so for three reasons: 1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript. 2. This was not an oversight: Douglas Crockford [wrote on this](https://plus.google.com/118095276221607585885/posts/RK8qyGVaGSr) in May 2012: - > I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't. + > I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't. > Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser. @@ -1574,13 +1579,15 @@ However, you can pass set parameter `ignore_comments` to true in the `parse` fun ### Order of object keys -By default, the library does not preserve the **insertion order of object elements**. This is standards-compliant, as the [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs". If you do want to preserve the insertion order, you can specialize the object type with containers like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)). +By default, the library does not preserve the **insertion order of object elements**. This is standards-compliant, as the [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs". + +If you do want to preserve the insertion order, you can try the type [`nlohmann::ordered_json`](https://github.com/nlohmann/json/issues/2179). Alternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)). ### Memory Release -We checked with Valgrind and the Address Sanitizer (ASAN) that there are no memory leaks. +We checked with Valgrind and the Address Sanitizer (ASAN) that there are no memory leaks. -If you find that a parsing program with this library does not release memory, please consider the following case and it maybe unrelated to this library. +If you find that a parsing program with this library does not release memory, please consider the following case and it maybe unrelated to this library. **Your program is compiled with glibc.** There is a tunable threshold that glibc uses to decide whether to actually return memory to the system or whether to cache it for later reuse. If in your program you make lots of small allocations and those small allocations are not a contiguous block and are presumably below the threshold, then they will not get returned to the OS. Here is a related issue [#1924](https://github.com/nlohmann/json/issues/1924). diff --git a/cmake/pkg-config.pc.in b/cmake/pkg-config.pc.in index 680f10c26d..3541abf0ba 100644 --- a/cmake/pkg-config.pc.in +++ b/cmake/pkg-config.pc.in @@ -1,4 +1,4 @@ Name: ${PROJECT_NAME} -Description: ${PROJECT_DESCRIPTION} +Description: JSON for Modern C++ Version: ${PROJECT_VERSION} Cflags: -I${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} diff --git a/include/nlohmann/adl_serializer.hpp b/include/nlohmann/adl_serializer.hpp index eeaa142574..4af1c4bb1d 100644 --- a/include/nlohmann/adl_serializer.hpp +++ b/include/nlohmann/adl_serializer.hpp @@ -37,7 +37,7 @@ struct adl_serializer @param[in,out] j JSON value to write to @param[in] val value to read from */ - template + template static auto to_json(BasicJsonType& j, ValueType&& val) noexcept( noexcept(::nlohmann::to_json(j, std::forward(val)))) -> decltype(::nlohmann::to_json(j, std::forward(val)), void()) diff --git a/include/nlohmann/detail/boolean_operators.hpp b/include/nlohmann/detail/boolean_operators.hpp deleted file mode 100644 index 06335866b1..0000000000 --- a/include/nlohmann/detail/boolean_operators.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Header is removed in C++20. -// See for more information. - -#if __cplusplus <= 201703L - #include // and, not, or -#endif diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index e8731f2235..03e8d367e8 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -12,7 +12,6 @@ #include // pair, declval #include // valarray -#include #include #include #include @@ -26,7 +25,7 @@ namespace detail template void from_json(const BasicJsonType& j, typename std::nullptr_t& n) { - if (JSON_HEDLEY_UNLIKELY(not j.is_null())) + if (JSON_HEDLEY_UNLIKELY(!j.is_null())) { JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()))); } @@ -34,10 +33,10 @@ void from_json(const BasicJsonType& j, typename std::nullptr_t& n) } // overloads for basic_json template parameters -template::value and - not std::is_same::value, - int> = 0> +template < typename BasicJsonType, typename ArithmeticType, + enable_if_t < std::is_arithmetic::value&& + !std::is_same::value, + int > = 0 > void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) { switch (static_cast(j)) @@ -66,7 +65,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) template void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) { - if (JSON_HEDLEY_UNLIKELY(not j.is_boolean())) + if (JSON_HEDLEY_UNLIKELY(!j.is_boolean())) { JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()))); } @@ -76,7 +75,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) template void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) { - if (JSON_HEDLEY_UNLIKELY(not j.is_string())) + if (JSON_HEDLEY_UNLIKELY(!j.is_string())) { JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()))); } @@ -86,13 +85,13 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) template < typename BasicJsonType, typename ConstructibleStringType, enable_if_t < - is_constructible_string_type::value and - not std::is_same::value, + is_constructible_string_type::value&& + !std::is_same::value, int > = 0 > void from_json(const BasicJsonType& j, ConstructibleStringType& s) { - if (JSON_HEDLEY_UNLIKELY(not j.is_string())) + if (JSON_HEDLEY_UNLIKELY(!j.is_string())) { JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()))); } @@ -132,7 +131,7 @@ template::value, int> = 0> void from_json(const BasicJsonType& j, std::forward_list& l) { - if (JSON_HEDLEY_UNLIKELY(not j.is_array())) + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) { JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); } @@ -149,7 +148,7 @@ template::value, int> = 0> void from_json(const BasicJsonType& j, std::valarray& l) { - if (JSON_HEDLEY_UNLIKELY(not j.is_array())) + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) { JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); } @@ -157,7 +156,7 @@ void from_json(const BasicJsonType& j, std::valarray& l) std::copy(j.begin(), j.end(), std::begin(l)); } -template +template auto from_json(const BasicJsonType& j, T (&arr)[N]) -> decltype(j.template get(), void()) { @@ -173,7 +172,7 @@ void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_ arr = *j.template get_ptr(); } -template +template auto from_json_array_impl(const BasicJsonType& j, std::array& arr, priority_tag<2> /*unused*/) -> decltype(j.template get(), void()) @@ -205,7 +204,7 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p arr = std::move(ret); } -template +template void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<0> /*unused*/) { @@ -223,20 +222,20 @@ void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, arr = std::move(ret); } -template ::value and - not is_constructible_object_type::value and - not is_constructible_string_type::value and - not std::is_same::value and - not is_basic_json::value, - int > = 0 > +template < typename BasicJsonType, typename ConstructibleArrayType, + enable_if_t < + is_constructible_array_type::value&& + !is_constructible_object_type::value&& + !is_constructible_string_type::value&& + !std::is_same::value&& + !is_basic_json::value, + int > = 0 > auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), j.template get(), void()) { - if (JSON_HEDLEY_UNLIKELY(not j.is_array())) + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) { JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); @@ -245,10 +244,10 @@ void()) from_json_array_impl(j, arr, priority_tag<3> {}); } -template +template void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin) { - if (JSON_HEDLEY_UNLIKELY(not j.is_binary())) + if (JSON_HEDLEY_UNLIKELY(!j.is_binary())) { JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()))); } @@ -260,7 +259,7 @@ template::value, int> = 0> void from_json(const BasicJsonType& j, ConstructibleObjectType& obj) { - if (JSON_HEDLEY_UNLIKELY(not j.is_object())) + if (JSON_HEDLEY_UNLIKELY(!j.is_object())) { JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()))); } @@ -282,14 +281,14 @@ void from_json(const BasicJsonType& j, ConstructibleObjectType& obj) // (BooleanType, etc..); note: Is it really necessary to provide explicit // overloads for boolean_t etc. in case of a custom BooleanType which is not // an arithmetic type? -template::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value, - int> = 0> +template < typename BasicJsonType, typename ArithmeticType, + enable_if_t < + std::is_arithmetic::value&& + !std::is_same::value&& + !std::is_same::value&& + !std::is_same::value&& + !std::is_same::value, + int > = 0 > void from_json(const BasicJsonType& j, ArithmeticType& val) { switch (static_cast(j)) @@ -338,19 +337,19 @@ void from_json(const BasicJsonType& j, std::tuple& t) from_json_tuple_impl(j, t, index_sequence_for {}); } -template ::value>> +template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, + typename = enable_if_t < !std::is_constructible < + typename BasicJsonType::string_t, Key >::value >> void from_json(const BasicJsonType& j, std::map& m) { - if (JSON_HEDLEY_UNLIKELY(not j.is_array())) + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) { JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); } m.clear(); for (const auto& p : j) { - if (JSON_HEDLEY_UNLIKELY(not p.is_array())) + if (JSON_HEDLEY_UNLIKELY(!p.is_array())) { JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()))); } @@ -358,19 +357,19 @@ void from_json(const BasicJsonType& j, std::map& } } -template ::value>> +template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator, + typename = enable_if_t < !std::is_constructible < + typename BasicJsonType::string_t, Key >::value >> void from_json(const BasicJsonType& j, std::unordered_map& m) { - if (JSON_HEDLEY_UNLIKELY(not j.is_array())) + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) { JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); } m.clear(); for (const auto& p : j) { - if (JSON_HEDLEY_UNLIKELY(not p.is_array())) + if (JSON_HEDLEY_UNLIKELY(!p.is_array())) { JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()))); } diff --git a/include/nlohmann/detail/conversions/to_chars.hpp b/include/nlohmann/detail/conversions/to_chars.hpp index 0907e76565..c632ff2bea 100644 --- a/include/nlohmann/detail/conversions/to_chars.hpp +++ b/include/nlohmann/detail/conversions/to_chars.hpp @@ -7,7 +7,6 @@ #include // numeric_limits #include // conditional -#include #include namespace nlohmann @@ -37,7 +36,7 @@ For a detailed description of the algorithm see: namespace dtoa_impl { -template +template Target reinterpret_bits(const Source source) { static_assert(sizeof(Target) == sizeof(Source), "size mismatch"); @@ -178,7 +177,7 @@ boundaries. @pre value must be finite and positive */ -template +template boundaries compute_boundaries(FloatType value) { JSON_ASSERT(std::isfinite(value)); @@ -231,7 +230,7 @@ boundaries compute_boundaries(FloatType value) // -----------------+------+------+-------------+-------------+--- (B) // v- m- v m+ v+ - const bool lower_boundary_is_closer = F == 0 and E > 1; + const bool lower_boundary_is_closer = F == 0 && E > 1; const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1); const diyfp m_minus = lower_boundary_is_closer ? diyfp(4 * v.f - 1, v.e - 2) // (B) @@ -566,8 +565,8 @@ inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t d // integer arithmetic. while (rest < dist - and delta - rest >= ten_k - and (rest + ten_k < dist or dist - rest > rest + ten_k - dist)) + && delta - rest >= ten_k + && (rest + ten_k < dist || dist - rest > rest + ten_k - dist)) { JSON_ASSERT(buf[len - 1] != '0'); buf[len - 1]--; @@ -878,7 +877,7 @@ v = buf * 10^decimal_exponent len is the length of the buffer (number of decimal digits) The buffer must be large enough, i.e. >= max_digits10. */ -template +template JSON_HEDLEY_NON_NULL(1) void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value) { @@ -985,7 +984,7 @@ inline char* format_buffer(char* buf, int len, int decimal_exponent, // k is the length of the buffer (number of decimal digits) // n is the position of the decimal point relative to the start of the buffer. - if (k <= n and n <= max_exp) + if (k <= n && n <= max_exp) { // digits[000] // len <= max_exp + 2 @@ -997,7 +996,7 @@ inline char* format_buffer(char* buf, int len, int decimal_exponent, return buf + (static_cast(n) + 2); } - if (0 < n and n <= max_exp) + if (0 < n && n <= max_exp) { // dig.its // len <= max_digits10 + 1 @@ -1009,7 +1008,7 @@ inline char* format_buffer(char* buf, int len, int decimal_exponent, return buf + (static_cast(k) + 1U); } - if (min_exp < n and n <= 0) + if (min_exp < n && n <= 0) { // 0.[000]digits // len <= 2 + (-min_exp - 1) + max_digits10 @@ -1054,7 +1053,7 @@ format. Returns an iterator pointing past-the-end of the decimal representation. @note The buffer must be large enough. @note The result is NOT null-terminated. */ -template +template JSON_HEDLEY_NON_NULL(1, 2) JSON_HEDLEY_RETURNS_NON_NULL char* to_chars(char* first, const char* last, FloatType value) diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp index cae779c53d..b45004fd42 100644 --- a/include/nlohmann/detail/conversions/to_json.hpp +++ b/include/nlohmann/detail/conversions/to_json.hpp @@ -9,7 +9,6 @@ #include // valarray #include // vector -#include #include #include #include @@ -56,9 +55,9 @@ struct external_constructor j.assert_invariant(); } - template::value, - int> = 0> + template < typename BasicJsonType, typename CompatibleStringType, + enable_if_t < !std::is_same::value, + int > = 0 > static void construct(BasicJsonType& j, const CompatibleStringType& str) { j.m_type = value_t::string; @@ -144,9 +143,9 @@ struct external_constructor j.assert_invariant(); } - template::value, - int> = 0> + template < typename BasicJsonType, typename CompatibleArrayType, + enable_if_t < !std::is_same::value, + int > = 0 > static void construct(BasicJsonType& j, const CompatibleArrayType& arr) { using std::begin; @@ -203,8 +202,8 @@ struct external_constructor j.assert_invariant(); } - template::value, int> = 0> + template < typename BasicJsonType, typename CompatibleObjectType, + enable_if_t < !std::is_same::value, int > = 0 > static void construct(BasicJsonType& j, const CompatibleObjectType& obj) { using std::begin; @@ -275,20 +274,20 @@ void to_json(BasicJsonType& j, const std::vector& e) external_constructor::construct(j, e); } -template ::value and - not is_compatible_object_type::value and - not is_compatible_string_type::value and - not std::is_same::value and - not is_basic_json::value, - int> = 0> +template < typename BasicJsonType, typename CompatibleArrayType, + enable_if_t < is_compatible_array_type::value&& + !is_compatible_object_type::value&& + !is_compatible_string_type::value&& + !std::is_same::value&& + !is_basic_json::value, + int > = 0 > void to_json(BasicJsonType& j, const CompatibleArrayType& arr) { external_constructor::construct(j, arr); } -template +template void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin) { external_constructor::construct(j, bin); @@ -307,8 +306,8 @@ void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr) external_constructor::construct(j, std::move(arr)); } -template::value and not is_basic_json::value, int> = 0> +template < typename BasicJsonType, typename CompatibleObjectType, + enable_if_t < is_compatible_object_type::value&& !is_basic_json::value, int > = 0 > void to_json(BasicJsonType& j, const CompatibleObjectType& obj) { external_constructor::construct(j, obj); @@ -322,9 +321,9 @@ void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) template < typename BasicJsonType, typename T, std::size_t N, - enable_if_t::value, - int> = 0 > + enable_if_t < !std::is_constructible::value, + int > = 0 > void to_json(BasicJsonType& j, const T(&arr)[N]) { external_constructor::construct(j, arr); @@ -337,8 +336,8 @@ void to_json(BasicJsonType& j, const std::pair& p) } // for https://github.com/nlohmann/json/pull/1134 -template < typename BasicJsonType, typename T, - enable_if_t>::value, int> = 0> +template>::value, int> = 0> void to_json(BasicJsonType& j, const T& b) { j = { {b.key(), b.value()} }; diff --git a/include/nlohmann/detail/hash.hpp b/include/nlohmann/detail/hash.hpp new file mode 100644 index 0000000000..d3313e9685 --- /dev/null +++ b/include/nlohmann/detail/hash.hpp @@ -0,0 +1,117 @@ +#pragma once + +#include // size_t, uint8_t +#include // hash + +namespace nlohmann +{ +namespace detail +{ + +// boost::hash_combine +std::size_t combine(std::size_t seed, std::size_t h) noexcept +{ + seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); + return seed; +} + +/*! +@brief hash a JSON value + +The hash function tries to rely on std::hash where possible. Furthermore, the +type of the JSON value is taken into account to have different hash values for +null, 0, 0U, and false, etc. + +@tparam BasicJsonType basic_json specialization +@param j JSON value to hash +@return hash value of j +*/ +template +std::size_t hash(const BasicJsonType& j) +{ + using string_t = typename BasicJsonType::string_t; + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + + const auto type = static_cast(j.type()); + switch (j.type()) + { + case BasicJsonType::value_t::null: + case BasicJsonType::value_t::discarded: + { + return combine(type, 0); + } + + case BasicJsonType::value_t::object: + { + auto seed = combine(type, j.size()); + for (const auto& element : j.items()) + { + const auto h = std::hash {}(element.key()); + seed = combine(seed, h); + seed = combine(seed, hash(element.value())); + } + return seed; + } + + case BasicJsonType::value_t::array: + { + auto seed = combine(type, j.size()); + for (const auto& element : j) + { + seed = combine(seed, hash(element)); + } + return seed; + } + + case BasicJsonType::value_t::string: + { + const auto h = std::hash {}(j.template get_ref()); + return combine(type, h); + } + + case BasicJsonType::value_t::boolean: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case BasicJsonType::value_t::number_integer: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case nlohmann::detail::value_t::number_unsigned: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case nlohmann::detail::value_t::number_float: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case nlohmann::detail::value_t::binary: + { + auto seed = combine(type, j.get_binary().size()); + const auto h = std::hash {}(j.get_binary().has_subtype()); + seed = combine(seed, h); + seed = combine(seed, j.get_binary().subtype()); + for (const auto byte : j.get_binary()) + { + seed = combine(seed, std::hash {}(byte)); + } + return seed; + } + + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // LCOV_EXCL_LINE + } +} + +} // namespace detail +} // namespace nlohmann diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index e075d52725..a650b2d01f 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -24,6 +24,13 @@ namespace nlohmann namespace detail { +/// how to treat CBOR tags +enum class cbor_tag_handler_t +{ + error, ///< throw a parse_error exception in case of a tag + ignore ///< ignore tags +}; + /*! @brief determine system byte order @@ -78,13 +85,15 @@ class binary_reader @param[in] format the binary format to parse @param[in] sax_ a SAX event processor @param[in] strict whether to expect the input to be consumed completed + @param[in] tag_handler how to treat CBOR tags @return */ JSON_HEDLEY_NON_NULL(3) bool sax_parse(const input_format_t format, json_sax_t* sax_, - const bool strict = true) + const bool strict = true, + const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) { sax = sax_; bool result = false; @@ -96,7 +105,7 @@ class binary_reader break; case input_format_t::cbor: - result = parse_cbor_internal(); + result = parse_cbor_internal(true, tag_handler); break; case input_format_t::msgpack: @@ -112,7 +121,7 @@ class binary_reader } // strict mode: next byte must be EOF - if (result and strict) + if (result && strict) { if (format == input_format_t::ubjson) { @@ -147,12 +156,12 @@ class binary_reader std::int32_t document_size{}; get_number(input_format_t::bson, document_size); - if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) { return false; } - if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/false))) + if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false))) { return false; } @@ -173,7 +182,7 @@ class binary_reader while (true) { get(); - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring"))) { return false; } @@ -205,7 +214,7 @@ class binary_reader return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"))); } - return get_string(input_format_t::bson, len - static_cast(1), result) and get() != std::char_traits::eof(); + return get_string(input_format_t::bson, len - static_cast(1), result) && get() != std::char_traits::eof(); } /*! @@ -252,14 +261,14 @@ class binary_reader case 0x01: // double { double number{}; - return get_number(input_format_t::bson, number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::bson, number) && sax->number_float(static_cast(number), ""); } case 0x02: // string { std::int32_t len{}; string_t value; - return get_number(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value); + return get_number(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value); } case 0x03: // object @@ -276,7 +285,7 @@ class binary_reader { std::int32_t len{}; binary_t value; - return get_number(input_format_t::bson, len) and get_bson_binary(len, value) and sax->binary(value); + return get_number(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value); } case 0x08: // boolean @@ -292,13 +301,13 @@ class binary_reader case 0x10: // int32 { std::int32_t value{}; - return get_number(input_format_t::bson, value) and sax->number_integer(value); + return get_number(input_format_t::bson, value) && sax->number_integer(value); } case 0x12: // int64 { std::int64_t value{}; - return get_number(input_format_t::bson, value) and sax->number_integer(value); + return get_number(input_format_t::bson, value) && sax->number_integer(value); } default: // anything else not supported (yet) @@ -328,23 +337,23 @@ class binary_reader while (auto element_type = get()) { - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list"))) { return false; } const std::size_t element_type_parse_position = chars_read; - if (JSON_HEDLEY_UNLIKELY(not get_bson_cstr(key))) + if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key))) { return false; } - if (not is_array and not sax->key(key)) + if (!is_array && !sax->key(key)) { return false; } - if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position))) + if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position))) { return false; } @@ -365,12 +374,12 @@ class binary_reader std::int32_t document_size{}; get_number(input_format_t::bson, document_size); - if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) { return false; } - if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/true))) + if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true))) { return false; } @@ -386,10 +395,12 @@ class binary_reader @param[in] get_char whether a new character should be retrieved from the input (true, default) or whether the last read character should be considered instead + @param[in] tag_handler how CBOR tags should be treated @return whether a valid CBOR value was passed to the SAX parser */ - bool parse_cbor_internal(const bool get_char = true) + bool parse_cbor_internal(const bool get_char = true, + cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) { switch (get_char ? get() : current) { @@ -427,25 +438,25 @@ class binary_reader case 0x18: // Unsigned integer (one-byte uint8_t follows) { std::uint8_t number{}; - return get_number(input_format_t::cbor, number) and sax->number_unsigned(number); + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); } case 0x19: // Unsigned integer (two-byte uint16_t follows) { std::uint16_t number{}; - return get_number(input_format_t::cbor, number) and sax->number_unsigned(number); + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); } case 0x1A: // Unsigned integer (four-byte uint32_t follows) { std::uint32_t number{}; - return get_number(input_format_t::cbor, number) and sax->number_unsigned(number); + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); } case 0x1B: // Unsigned integer (eight-byte uint64_t follows) { std::uint64_t number{}; - return get_number(input_format_t::cbor, number) and sax->number_unsigned(number); + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); } // Negative integer -1-0x00..-1-0x17 (-1..-24) @@ -478,25 +489,25 @@ class binary_reader case 0x38: // Negative integer (one-byte uint8_t follows) { std::uint8_t number{}; - return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) - number); + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); } case 0x39: // Negative integer -1-n (two-byte uint16_t follows) { std::uint16_t number{}; - return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) - number); + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); } case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) { std::uint32_t number{}; - return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) - number); + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); } case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) { std::uint64_t number{}; - return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - static_cast(number)); } @@ -532,7 +543,7 @@ class binary_reader case 0x5F: // Binary data (indefinite length) { binary_t b; - return get_cbor_binary(b) and sax->binary(b); + return get_cbor_binary(b) && sax->binary(b); } // UTF-8 string (0x00..0x17 bytes follow) @@ -567,7 +578,7 @@ class binary_reader case 0x7F: // UTF-8 string (indefinite length) { string_t s; - return get_cbor_string(s) and sax->string(s); + return get_cbor_string(s) && sax->string(s); } // array (0x00..0x17 data items follow) @@ -600,25 +611,25 @@ class binary_reader case 0x98: // array (one-byte uint8_t for n follows) { std::uint8_t len{}; - return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); } case 0x99: // array (two-byte uint16_t for n follow) { std::uint16_t len{}; - return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); } case 0x9A: // array (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); } case 0x9B: // array (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); } case 0x9F: // array (indefinite length) @@ -654,30 +665,97 @@ class binary_reader case 0xB8: // map (one-byte uint8_t for n follows) { std::uint8_t len{}; - return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); } case 0xB9: // map (two-byte uint16_t for n follow) { std::uint16_t len{}; - return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); } case 0xBA: // map (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); } case 0xBB: // map (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); } case 0xBF: // map (indefinite length) return get_cbor_object(std::size_t(-1)); + case 0xC6: // tagged item + case 0xC7: + case 0xC8: + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: + case 0xD0: + case 0xD1: + case 0xD2: + case 0xD3: + case 0xD4: + case 0xD8: // tagged item (1 bytes follow) + case 0xD9: // tagged item (2 bytes follow) + case 0xDA: // tagged item (4 bytes follow) + case 0xDB: // tagged item (8 bytes follow) + { + switch (tag_handler) + { + case cbor_tag_handler_t::error: + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"))); + } + + case cbor_tag_handler_t::ignore: + { + switch (current) + { + case 0xD8: + { + std::uint8_t len{}; + get_number(input_format_t::cbor, len); + break; + } + case 0xD9: + { + std::uint16_t len{}; + get_number(input_format_t::cbor, len); + break; + } + case 0xDA: + { + std::uint32_t len{}; + get_number(input_format_t::cbor, len); + break; + } + case 0xDB: + { + std::uint64_t len{}; + get_number(input_format_t::cbor, len); + break; + } + default: + break; + } + return parse_cbor_internal(true, tag_handler); + } + + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // LCOV_EXCL_LINE + } + } + case 0xF4: // false return sax->boolean(false); @@ -690,12 +768,12 @@ class binary_reader case 0xF9: // Half-Precision Float (two-byte IEEE 754) { const auto byte1_raw = get(); - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) { return false; } const auto byte2_raw = get(); - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) { return false; } @@ -716,7 +794,7 @@ class binary_reader { const int exp = (half >> 10u) & 0x1Fu; const unsigned int mant = half & 0x3FFu; - JSON_ASSERT(0 <= exp and exp <= 32); + JSON_ASSERT(0 <= exp&& exp <= 32); JSON_ASSERT(mant <= 1024); switch (exp) { @@ -738,13 +816,13 @@ class binary_reader case 0xFA: // Single-Precision Float (four-byte IEEE 754) { float number{}; - return get_number(input_format_t::cbor, number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::cbor, number) && sax->number_float(static_cast(number), ""); } case 0xFB: // Double-Precision Float (eight-byte IEEE 754) { double number{}; - return get_number(input_format_t::cbor, number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::cbor, number) && sax->number_float(static_cast(number), ""); } default: // anything else (0xFF is handled inside the other types) @@ -768,7 +846,7 @@ class binary_reader */ bool get_cbor_string(string_t& result) { - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string"))) { return false; } @@ -807,25 +885,25 @@ class binary_reader case 0x78: // UTF-8 string (one-byte uint8_t for n follows) { std::uint8_t len{}; - return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result); + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); } case 0x79: // UTF-8 string (two-byte uint16_t for n follow) { std::uint16_t len{}; - return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result); + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); } case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result); + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); } case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result); + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); } case 0x7F: // UTF-8 string (indefinite length) @@ -833,7 +911,7 @@ class binary_reader while (get() != 0xFF) { string_t chunk; - if (not get_cbor_string(chunk)) + if (!get_cbor_string(chunk)) { return false; } @@ -863,7 +941,7 @@ class binary_reader */ bool get_cbor_binary(binary_t& result) { - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "binary"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary"))) { return false; } @@ -902,28 +980,28 @@ class binary_reader case 0x58: // Binary data (one-byte uint8_t for n follows) { std::uint8_t len{}; - return get_number(input_format_t::cbor, len) and + return get_number(input_format_t::cbor, len) && get_binary(input_format_t::cbor, len, result); } case 0x59: // Binary data (two-byte uint16_t for n follow) { std::uint16_t len{}; - return get_number(input_format_t::cbor, len) and + return get_number(input_format_t::cbor, len) && get_binary(input_format_t::cbor, len, result); } case 0x5A: // Binary data (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) and + return get_number(input_format_t::cbor, len) && get_binary(input_format_t::cbor, len, result); } case 0x5B: // Binary data (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) and + return get_number(input_format_t::cbor, len) && get_binary(input_format_t::cbor, len, result); } @@ -932,7 +1010,7 @@ class binary_reader while (get() != 0xFF) { binary_t chunk; - if (not get_cbor_binary(chunk)) + if (!get_cbor_binary(chunk)) { return false; } @@ -956,7 +1034,7 @@ class binary_reader */ bool get_cbor_array(const std::size_t len) { - if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) { return false; } @@ -965,7 +1043,7 @@ class binary_reader { for (std::size_t i = 0; i < len; ++i) { - if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal())) { return false; } @@ -975,7 +1053,7 @@ class binary_reader { while (get() != 0xFF) { - if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal(false))) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false))) { return false; } @@ -992,7 +1070,7 @@ class binary_reader */ bool get_cbor_object(const std::size_t len) { - if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) { return false; } @@ -1003,12 +1081,12 @@ class binary_reader for (std::size_t i = 0; i < len; ++i) { get(); - if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key))) + if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) { return false; } - if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal())) { return false; } @@ -1019,12 +1097,12 @@ class binary_reader { while (get() != 0xFF) { - if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key))) + if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) { return false; } - if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal())) { return false; } @@ -1257,7 +1335,7 @@ class binary_reader case 0xDB: // str 32 { string_t s; - return get_msgpack_string(s) and sax->string(s); + return get_msgpack_string(s) && sax->string(s); } case 0xC0: // nil @@ -1282,91 +1360,91 @@ class binary_reader case 0xD8: // fixext 16 { binary_t b; - return get_msgpack_binary(b) and sax->binary(b); + return get_msgpack_binary(b) && sax->binary(b); } case 0xCA: // float 32 { float number{}; - return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast(number), ""); } case 0xCB: // float 64 { double number{}; - return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast(number), ""); } case 0xCC: // uint 8 { std::uint8_t number{}; - return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number); + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); } case 0xCD: // uint 16 { std::uint16_t number{}; - return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number); + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); } case 0xCE: // uint 32 { std::uint32_t number{}; - return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number); + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); } case 0xCF: // uint 64 { std::uint64_t number{}; - return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number); + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); } case 0xD0: // int 8 { std::int8_t number{}; - return get_number(input_format_t::msgpack, number) and sax->number_integer(number); + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); } case 0xD1: // int 16 { std::int16_t number{}; - return get_number(input_format_t::msgpack, number) and sax->number_integer(number); + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); } case 0xD2: // int 32 { std::int32_t number{}; - return get_number(input_format_t::msgpack, number) and sax->number_integer(number); + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); } case 0xD3: // int 64 { std::int64_t number{}; - return get_number(input_format_t::msgpack, number) and sax->number_integer(number); + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); } case 0xDC: // array 16 { std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast(len)); + return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast(len)); } case 0xDD: // array 32 { std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast(len)); + return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast(len)); } case 0xDE: // map 16 { std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast(len)); + return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast(len)); } case 0xDF: // map 32 { std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast(len)); + return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast(len)); } // negative fixint @@ -1424,7 +1502,7 @@ class binary_reader */ bool get_msgpack_string(string_t& result) { - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string"))) { return false; } @@ -1471,19 +1549,19 @@ class binary_reader case 0xD9: // str 8 { std::uint8_t len{}; - return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result); + return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); } case 0xDA: // str 16 { std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result); + return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); } case 0xDB: // str 32 { std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result); + return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); } default: @@ -1518,21 +1596,21 @@ class binary_reader case 0xC4: // bin 8 { std::uint8_t len{}; - return get_number(input_format_t::msgpack, len) and + return get_number(input_format_t::msgpack, len) && get_binary(input_format_t::msgpack, len, result); } case 0xC5: // bin 16 { std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) and + return get_number(input_format_t::msgpack, len) && get_binary(input_format_t::msgpack, len, result); } case 0xC6: // bin 32 { std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) and + return get_number(input_format_t::msgpack, len) && get_binary(input_format_t::msgpack, len, result); } @@ -1540,9 +1618,9 @@ class binary_reader { std::uint8_t len{}; std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) and - get_number(input_format_t::msgpack, subtype) and - get_binary(input_format_t::msgpack, len, result) and + return get_number(input_format_t::msgpack, len) && + get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, len, result) && assign_and_return_true(subtype); } @@ -1550,9 +1628,9 @@ class binary_reader { std::uint16_t len{}; std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) and - get_number(input_format_t::msgpack, subtype) and - get_binary(input_format_t::msgpack, len, result) and + return get_number(input_format_t::msgpack, len) && + get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, len, result) && assign_and_return_true(subtype); } @@ -1560,49 +1638,49 @@ class binary_reader { std::uint32_t len{}; std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) and - get_number(input_format_t::msgpack, subtype) and - get_binary(input_format_t::msgpack, len, result) and + return get_number(input_format_t::msgpack, len) && + get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, len, result) && assign_and_return_true(subtype); } case 0xD4: // fixext 1 { std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) and - get_binary(input_format_t::msgpack, 1, result) and + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 1, result) && assign_and_return_true(subtype); } case 0xD5: // fixext 2 { std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) and - get_binary(input_format_t::msgpack, 2, result) and + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 2, result) && assign_and_return_true(subtype); } case 0xD6: // fixext 4 { std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) and - get_binary(input_format_t::msgpack, 4, result) and + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 4, result) && assign_and_return_true(subtype); } case 0xD7: // fixext 8 { std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) and - get_binary(input_format_t::msgpack, 8, result) and + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 8, result) && assign_and_return_true(subtype); } case 0xD8: // fixext 16 { std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) and - get_binary(input_format_t::msgpack, 16, result) and + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 16, result) && assign_and_return_true(subtype); } @@ -1617,14 +1695,14 @@ class binary_reader */ bool get_msgpack_array(const std::size_t len) { - if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) { return false; } for (std::size_t i = 0; i < len; ++i) { - if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) { return false; } @@ -1639,7 +1717,7 @@ class binary_reader */ bool get_msgpack_object(const std::size_t len) { - if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) { return false; } @@ -1648,12 +1726,12 @@ class binary_reader for (std::size_t i = 0; i < len; ++i) { get(); - if (JSON_HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key))) + if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key))) { return false; } - if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) { return false; } @@ -1700,7 +1778,7 @@ class binary_reader get(); // TODO(niels): may we ignore N here? } - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value"))) { return false; } @@ -1710,31 +1788,31 @@ class binary_reader case 'U': { std::uint8_t len{}; - return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result); + return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); } case 'i': { std::int8_t len{}; - return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result); + return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); } case 'I': { std::int16_t len{}; - return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result); + return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); } case 'l': { std::int32_t len{}; - return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result); + return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); } case 'L': { std::int64_t len{}; - return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result); + return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); } default: @@ -1754,7 +1832,7 @@ class binary_reader case 'U': { std::uint8_t number{}; - if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number))) + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) { return false; } @@ -1765,7 +1843,7 @@ class binary_reader case 'i': { std::int8_t number{}; - if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number))) + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) { return false; } @@ -1776,7 +1854,7 @@ class binary_reader case 'I': { std::int16_t number{}; - if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number))) + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) { return false; } @@ -1787,7 +1865,7 @@ class binary_reader case 'l': { std::int32_t number{}; - if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number))) + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) { return false; } @@ -1798,7 +1876,7 @@ class binary_reader case 'L': { std::int64_t number{}; - if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number))) + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) { return false; } @@ -1834,7 +1912,7 @@ class binary_reader if (current == '$') { result.second = get(); // must not ignore 'N', because 'N' maybe the type - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type"))) { return false; } @@ -1842,7 +1920,7 @@ class binary_reader get_ignore_noop(); if (JSON_HEDLEY_UNLIKELY(current != '#')) { - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value"))) { return false; } @@ -1883,49 +1961,49 @@ class binary_reader case 'U': { std::uint8_t number{}; - return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number); + return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number); } case 'i': { std::int8_t number{}; - return get_number(input_format_t::ubjson, number) and sax->number_integer(number); + return get_number(input_format_t::ubjson, number) && sax->number_integer(number); } case 'I': { std::int16_t number{}; - return get_number(input_format_t::ubjson, number) and sax->number_integer(number); + return get_number(input_format_t::ubjson, number) && sax->number_integer(number); } case 'l': { std::int32_t number{}; - return get_number(input_format_t::ubjson, number) and sax->number_integer(number); + return get_number(input_format_t::ubjson, number) && sax->number_integer(number); } case 'L': { std::int64_t number{}; - return get_number(input_format_t::ubjson, number) and sax->number_integer(number); + return get_number(input_format_t::ubjson, number) && sax->number_integer(number); } case 'd': { float number{}; - return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast(number), ""); } case 'D': { double number{}; - return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast(number), ""); } case 'C': // char { get(); - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char"))) { return false; } @@ -1941,7 +2019,7 @@ class binary_reader case 'S': // string { string_t s; - return get_ubjson_string(s) and sax->string(s); + return get_ubjson_string(s) && sax->string(s); } case '[': // array @@ -1964,14 +2042,14 @@ class binary_reader bool get_ubjson_array() { std::pair size_and_type; - if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type))) + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) { return false; } if (size_and_type.first != string_t::npos) { - if (JSON_HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first))) { return false; } @@ -1982,7 +2060,7 @@ class binary_reader { for (std::size_t i = 0; i < size_and_type.first; ++i) { - if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second))) + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) { return false; } @@ -1993,7 +2071,7 @@ class binary_reader { for (std::size_t i = 0; i < size_and_type.first; ++i) { - if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) { return false; } @@ -2002,14 +2080,14 @@ class binary_reader } else { - if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) { return false; } while (current != ']') { - if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal(false))) + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false))) { return false; } @@ -2026,7 +2104,7 @@ class binary_reader bool get_ubjson_object() { std::pair size_and_type; - if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type))) + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) { return false; } @@ -2034,7 +2112,7 @@ class binary_reader string_t key; if (size_and_type.first != string_t::npos) { - if (JSON_HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first))) { return false; } @@ -2043,11 +2121,11 @@ class binary_reader { for (std::size_t i = 0; i < size_and_type.first; ++i) { - if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key))) + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) { return false; } - if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second))) + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) { return false; } @@ -2058,11 +2136,11 @@ class binary_reader { for (std::size_t i = 0; i < size_and_type.first; ++i) { - if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key))) + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) { return false; } - if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) { return false; } @@ -2072,18 +2150,18 @@ class binary_reader } else { - if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) { return false; } while (current != '}') { - if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key))) + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key))) { return false; } - if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) { return false; } @@ -2152,7 +2230,7 @@ class binary_reader for (std::size_t i = 0; i < sizeof(NumberType); ++i) { get(); - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "number"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number"))) { return false; } @@ -2196,7 +2274,7 @@ class binary_reader std::generate_n(std::back_inserter(result), len, [this, &success, &format]() { get(); - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "string"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string"))) { success = false; } @@ -2228,7 +2306,7 @@ class binary_reader std::generate_n(std::back_inserter(result), len, [this, &success, &format]() { get(); - if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "binary"))) + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary"))) { success = false; } diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index 2efccb1ad2..63921ca55c 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -36,7 +36,7 @@ class file_input_adapter using char_type = char; JSON_HEDLEY_NON_NULL(2) - explicit file_input_adapter(std::FILE* f) noexcept + explicit file_input_adapter(std::FILE* f) noexcept : m_file(f) {} @@ -90,7 +90,7 @@ class input_stream_adapter input_stream_adapter& operator=(input_stream_adapter&) = delete; input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete; - input_stream_adapter(input_stream_adapter&& rhs) : is(rhs.is), sb(rhs.sb) + input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb) { rhs.is = nullptr; rhs.sb = nullptr; @@ -250,7 +250,7 @@ struct wide_string_input_helper utf8_bytes[1] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); utf8_bytes_filled = 2; } - else if (0xD800 > wc or wc >= 0xE000) + else if (0xD800 > wc || wc >= 0xE000) { utf8_bytes[0] = static_cast::int_type>(0xE0u | ((static_cast(wc) >> 12u))); utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); @@ -259,7 +259,7 @@ struct wide_string_input_helper } else { - if (JSON_HEDLEY_UNLIKELY(not input.empty())) + if (JSON_HEDLEY_UNLIKELY(!input.empty())) { const auto wc2 = static_cast(input.get_character()); const auto charcode = 0x10000u + (((static_cast(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu)); @@ -402,9 +402,9 @@ using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval::value and - not std::is_array::value and - std::is_integral::type>::value and + std::is_pointer::value&& + !std::is_array::value&& + std::is_integral::type>::value&& sizeof(typename std::remove_pointer::type) == 1, int >::type = 0 > contiguous_bytes_input_adapter input_adapter(CharT b) @@ -426,12 +426,12 @@ auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) class span_input_adapter { public: - template::value and - std::is_integral::type>::value and - sizeof(typename std::remove_pointer::type) == 1, - int>::type = 0> + template < typename CharT, + typename std::enable_if < + std::is_pointer::value&& + std::is_integral::type>::value&& + sizeof(typename std::remove_pointer::type) == 1, + int >::type = 0 > span_input_adapter(CharT b, std::size_t l) : ia(reinterpret_cast(b), reinterpret_cast(b) + l) {} diff --git a/include/nlohmann/detail/input/json_sax.hpp b/include/nlohmann/detail/input/json_sax.hpp index 18d82822c0..ae6a6cbe22 100644 --- a/include/nlohmann/detail/input/json_sax.hpp +++ b/include/nlohmann/detail/input/json_sax.hpp @@ -217,7 +217,7 @@ class json_sax_dom_parser { ref_stack.push_back(handle_value(BasicJsonType::value_t::object)); - if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) + if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) { JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len))); @@ -243,7 +243,7 @@ class json_sax_dom_parser { ref_stack.push_back(handle_value(BasicJsonType::value_t::array)); - if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) + if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) { JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len))); @@ -258,30 +258,14 @@ class json_sax_dom_parser return true; } + template bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, - const detail::exception& ex) + const Exception& ex) { errored = true; if (allow_exceptions) { - // determine the proper exception type from the id - switch ((ex.id / 100) % 100) - { - case 1: - JSON_THROW(*dynamic_cast(&ex)); - case 4: - JSON_THROW(*dynamic_cast(&ex)); - // LCOV_EXCL_START - case 2: - JSON_THROW(*dynamic_cast(&ex)); - case 3: - JSON_THROW(*dynamic_cast(&ex)); - case 5: - JSON_THROW(*dynamic_cast(&ex)); - default: - JSON_ASSERT(false); - // LCOV_EXCL_STOP - } + JSON_THROW(ex); } return false; } @@ -308,7 +292,7 @@ class json_sax_dom_parser return &root; } - JSON_ASSERT(ref_stack.back()->is_array() or ref_stack.back()->is_object()); + JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); if (ref_stack.back()->is_array()) { @@ -413,7 +397,7 @@ class json_sax_dom_callback_parser ref_stack.push_back(val.second); // check object limit - if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) + if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) { JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len))); } @@ -430,7 +414,7 @@ class json_sax_dom_callback_parser key_keep_stack.push_back(keep); // add discarded value at given key and store the reference for later - if (keep and ref_stack.back()) + if (keep && ref_stack.back()) { object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded); } @@ -440,18 +424,18 @@ class json_sax_dom_callback_parser bool end_object() { - if (ref_stack.back() and not callback(static_cast(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back())) + if (ref_stack.back() && !callback(static_cast(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back())) { // discard object *ref_stack.back() = discarded; } - JSON_ASSERT(not ref_stack.empty()); - JSON_ASSERT(not keep_stack.empty()); + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(!keep_stack.empty()); ref_stack.pop_back(); keep_stack.pop_back(); - if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_structured()) + if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured()) { // remove discarded value for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it) @@ -476,7 +460,7 @@ class json_sax_dom_callback_parser ref_stack.push_back(val.second); // check array limit - if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) + if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) { JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len))); } @@ -491,20 +475,20 @@ class json_sax_dom_callback_parser if (ref_stack.back()) { keep = callback(static_cast(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back()); - if (not keep) + if (!keep) { // discard array *ref_stack.back() = discarded; } } - JSON_ASSERT(not ref_stack.empty()); - JSON_ASSERT(not keep_stack.empty()); + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(!keep_stack.empty()); ref_stack.pop_back(); keep_stack.pop_back(); // remove discarded value - if (not keep and not ref_stack.empty() and ref_stack.back()->is_array()) + if (!keep && !ref_stack.empty() && ref_stack.back()->is_array()) { ref_stack.back()->m_value.array->pop_back(); } @@ -512,30 +496,14 @@ class json_sax_dom_callback_parser return true; } + template bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, - const detail::exception& ex) + const Exception& ex) { errored = true; if (allow_exceptions) { - // determine the proper exception type from the id - switch ((ex.id / 100) % 100) - { - case 1: - JSON_THROW(*dynamic_cast(&ex)); - case 4: - JSON_THROW(*dynamic_cast(&ex)); - // LCOV_EXCL_START - case 2: - JSON_THROW(*dynamic_cast(&ex)); - case 3: - JSON_THROW(*dynamic_cast(&ex)); - case 5: - JSON_THROW(*dynamic_cast(&ex)); - default: - JSON_ASSERT(false); - // LCOV_EXCL_STOP - } + JSON_THROW(ex); } return false; } @@ -564,11 +532,11 @@ class json_sax_dom_callback_parser template std::pair handle_value(Value&& v, const bool skip_callback = false) { - JSON_ASSERT(not keep_stack.empty()); + JSON_ASSERT(!keep_stack.empty()); // do not handle this value if we know it would be added to a discarded // container - if (not keep_stack.back()) + if (!keep_stack.back()) { return {false, nullptr}; } @@ -577,10 +545,10 @@ class json_sax_dom_callback_parser auto value = BasicJsonType(std::forward(v)); // check callback - const bool keep = skip_callback or callback(static_cast(ref_stack.size()), parse_event_t::value, value); + const bool keep = skip_callback || callback(static_cast(ref_stack.size()), parse_event_t::value, value); // do not handle this value if we just learnt it shall be discarded - if (not keep) + if (!keep) { return {false, nullptr}; } @@ -593,13 +561,13 @@ class json_sax_dom_callback_parser // skip this value if we already decided to skip the parent // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360) - if (not ref_stack.back()) + if (!ref_stack.back()) { return {false, nullptr}; } // we now only expect arrays and objects - JSON_ASSERT(ref_stack.back()->is_array() or ref_stack.back()->is_object()); + JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); // array if (ref_stack.back()->is_array()) @@ -611,11 +579,11 @@ class json_sax_dom_callback_parser // object JSON_ASSERT(ref_stack.back()->is_object()); // check if we should store an element for the current key - JSON_ASSERT(not key_keep_stack.empty()); + JSON_ASSERT(!key_keep_stack.empty()); const bool store_element = key_keep_stack.back(); key_keep_stack.pop_back(); - if (not store_element) + if (!store_element) { return {false, nullptr}; } diff --git a/include/nlohmann/detail/input/lexer.hpp b/include/nlohmann/detail/input/lexer.hpp index 0a0c6c74e1..60eb3526f0 100644 --- a/include/nlohmann/detail/input/lexer.hpp +++ b/include/nlohmann/detail/input/lexer.hpp @@ -169,15 +169,15 @@ class lexer : public lexer_base { get(); - if (current >= '0' and current <= '9') + if (current >= '0' && current <= '9') { codepoint += static_cast((static_cast(current) - 0x30u) << factor); } - else if (current >= 'A' and current <= 'F') + else if (current >= 'A' && current <= 'F') { codepoint += static_cast((static_cast(current) - 0x37u) << factor); } - else if (current >= 'a' and current <= 'f') + else if (current >= 'a' && current <= 'f') { codepoint += static_cast((static_cast(current) - 0x57u) << factor); } @@ -187,7 +187,7 @@ class lexer : public lexer_base } } - JSON_ASSERT(0x0000 <= codepoint and codepoint <= 0xFFFF); + JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF); return codepoint; } @@ -208,13 +208,13 @@ class lexer : public lexer_base */ bool next_byte_in_range(std::initializer_list ranges) { - JSON_ASSERT(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6); + JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6); add(current); for (auto range = ranges.begin(); range != ranges.end(); ++range) { get(); - if (JSON_HEDLEY_LIKELY(*range <= current and current <= *(++range))) + if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) { add(current); } @@ -320,10 +320,10 @@ class lexer : public lexer_base } // check if code point is a high surrogate - if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF) + if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF) { // expect next \uxxxx entry - if (JSON_HEDLEY_LIKELY(get() == '\\' and get() == 'u')) + if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u')) { const int codepoint2 = get_codepoint(); @@ -334,7 +334,7 @@ class lexer : public lexer_base } // check if codepoint2 is a low surrogate - if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF)) + if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF)) { // overwrite codepoint codepoint = static_cast( @@ -361,7 +361,7 @@ class lexer : public lexer_base } else { - if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF)) + if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF)) { error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF"; return token_type::parse_error; @@ -369,7 +369,7 @@ class lexer : public lexer_base } // result of the above calculation yields a proper codepoint - JSON_ASSERT(0x00 <= codepoint and codepoint <= 0x10FFFF); + JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF); // translate codepoint into bytes if (codepoint < 0x80) @@ -736,7 +736,7 @@ class lexer : public lexer_base case 0xDE: case 0xDF: { - if (JSON_HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF}))) + if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF}))) { return token_type::parse_error; } @@ -746,7 +746,7 @@ class lexer : public lexer_base // U+0800..U+0FFF: bytes E0 A0..BF 80..BF case 0xE0: { - if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) { return token_type::parse_error; } @@ -770,7 +770,7 @@ class lexer : public lexer_base case 0xEE: case 0xEF: { - if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) { return token_type::parse_error; } @@ -780,7 +780,7 @@ class lexer : public lexer_base // U+D000..U+D7FF: bytes ED 80..9F 80..BF case 0xED: { - if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) { return token_type::parse_error; } @@ -790,7 +790,7 @@ class lexer : public lexer_base // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF case 0xF0: { - if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) { return token_type::parse_error; } @@ -802,7 +802,7 @@ class lexer : public lexer_base case 0xF2: case 0xF3: { - if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) { return token_type::parse_error; } @@ -812,7 +812,7 @@ class lexer : public lexer_base // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF case 0xF4: { - if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) { return token_type::parse_error; } @@ -1384,7 +1384,7 @@ class lexer : public lexer_base if (JSON_HEDLEY_LIKELY(current != std::char_traits::eof())) { - JSON_ASSERT(not token_string.empty()); + JSON_ASSERT(!token_string.empty()); token_string.pop_back(); } } @@ -1480,7 +1480,7 @@ class lexer : public lexer_base if (get() == 0xEF) { // check if we completely parse the BOM - return get() == 0xBB and get() == 0xBF; + return get() == 0xBB && get() == 0xBF; } // the first character is not the beginning of the BOM; unget it to @@ -1495,13 +1495,13 @@ class lexer : public lexer_base { get(); } - while (current == ' ' or current == '\t' or current == '\n' or current == '\r'); + while (current == ' ' || current == '\t' || current == '\n' || current == '\r'); } token_type scan() { // initially, skip the BOM - if (position.chars_read_total == 0 and not skip_bom()) + if (position.chars_read_total == 0 && !skip_bom()) { error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given"; return token_type::parse_error; @@ -1511,9 +1511,9 @@ class lexer : public lexer_base skip_whitespace(); // ignore comments - if (ignore_comments and current == '/') + if (ignore_comments && current == '/') { - if (not scan_comment()) + if (!scan_comment()) { return token_type::parse_error; } diff --git a/include/nlohmann/detail/input/parser.hpp b/include/nlohmann/detail/input/parser.hpp index b9f7cd842a..ffe483aa1e 100644 --- a/include/nlohmann/detail/input/parser.hpp +++ b/include/nlohmann/detail/input/parser.hpp @@ -91,7 +91,7 @@ class parser result.assert_invariant(); // in strict mode, input must be completely read - if (strict and (get_token() != token_type::end_of_input)) + if (strict && (get_token() != token_type::end_of_input)) { sdp.parse_error(m_lexer.get_position(), m_lexer.get_token_string(), @@ -120,7 +120,7 @@ class parser result.assert_invariant(); // in strict mode, input must be completely read - if (strict and (get_token() != token_type::end_of_input)) + if (strict && (get_token() != token_type::end_of_input)) { sdp.parse_error(m_lexer.get_position(), m_lexer.get_token_string(), @@ -149,7 +149,7 @@ class parser return sax_parse(&sax_acceptor, strict); } - template + template JSON_HEDLEY_NON_NULL(2) bool sax_parse(SAX* sax, const bool strict = true) { @@ -157,7 +157,7 @@ class parser const bool result = sax_parse_internal(sax); // strict mode: next byte must be EOF - if (result and strict and (get_token() != token_type::end_of_input)) + if (result && strict && (get_token() != token_type::end_of_input)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), @@ -169,7 +169,7 @@ class parser } private: - template + template JSON_HEDLEY_NON_NULL(2) bool sax_parse_internal(SAX* sax) { @@ -181,14 +181,14 @@ class parser while (true) { - if (not skip_to_state_evaluation) + if (!skip_to_state_evaluation) { // invariant: get_token() was called before each iteration switch (last_token) { case token_type::begin_object: { - if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) { return false; } @@ -196,7 +196,7 @@ class parser // closing } -> we are done if (get_token() == token_type::end_object) { - if (JSON_HEDLEY_UNLIKELY(not sax->end_object())) + if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) { return false; } @@ -211,7 +211,7 @@ class parser parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"))); } - if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string()))) + if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) { return false; } @@ -235,7 +235,7 @@ class parser case token_type::begin_array: { - if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) { return false; } @@ -243,7 +243,7 @@ class parser // closing ] -> we are done if (get_token() == token_type::end_array) { - if (JSON_HEDLEY_UNLIKELY(not sax->end_array())) + if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) { return false; } @@ -261,14 +261,14 @@ class parser { const auto res = m_lexer.get_number_float(); - if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res))) + if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res))) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'")); } - if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string()))) + if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string()))) { return false; } @@ -278,7 +278,7 @@ class parser case token_type::literal_false: { - if (JSON_HEDLEY_UNLIKELY(not sax->boolean(false))) + if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false))) { return false; } @@ -287,7 +287,7 @@ class parser case token_type::literal_null: { - if (JSON_HEDLEY_UNLIKELY(not sax->null())) + if (JSON_HEDLEY_UNLIKELY(!sax->null())) { return false; } @@ -296,7 +296,7 @@ class parser case token_type::literal_true: { - if (JSON_HEDLEY_UNLIKELY(not sax->boolean(true))) + if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true))) { return false; } @@ -305,7 +305,7 @@ class parser case token_type::value_integer: { - if (JSON_HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer()))) + if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer()))) { return false; } @@ -314,7 +314,7 @@ class parser case token_type::value_string: { - if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string()))) + if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string()))) { return false; } @@ -323,7 +323,7 @@ class parser case token_type::value_unsigned: { - if (JSON_HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned()))) + if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned()))) { return false; } @@ -373,7 +373,7 @@ class parser // closing ] if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array)) { - if (JSON_HEDLEY_UNLIKELY(not sax->end_array())) + if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) { return false; } @@ -382,7 +382,7 @@ class parser // new value, we need to evaluate the new state first. // By setting skip_to_state_evaluation to false, we // are effectively jumping to the beginning of this if. - JSON_ASSERT(not states.empty()); + JSON_ASSERT(!states.empty()); states.pop_back(); skip_to_state_evaluation = true; continue; @@ -407,7 +407,7 @@ class parser exception_message(token_type::value_string, "object key"))); } - if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string()))) + if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) { return false; } @@ -429,7 +429,7 @@ class parser // closing } if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object)) { - if (JSON_HEDLEY_UNLIKELY(not sax->end_object())) + if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) { return false; } @@ -438,7 +438,7 @@ class parser // new value, we need to evaluate the new state first. // By setting skip_to_state_evaluation to false, we // are effectively jumping to the beginning of this if. - JSON_ASSERT(not states.empty()); + JSON_ASSERT(!states.empty()); states.pop_back(); skip_to_state_evaluation = true; continue; @@ -462,7 +462,7 @@ class parser { std::string error_msg = "syntax error "; - if (not context.empty()) + if (!context.empty()) { error_msg += "while parsing " + context + " "; } diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp index 8d7796e118..e9a394d4cc 100644 --- a/include/nlohmann/detail/iterators/iter_impl.hpp +++ b/include/nlohmann/detail/iterators/iter_impl.hpp @@ -3,7 +3,6 @@ #include // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next #include // conditional, is_const, remove_const -#include #include #include #include @@ -423,7 +422,7 @@ class iter_impl */ bool operator!=(const iter_impl& other) const { - return not operator==(other); + return !operator==(other); } /*! @@ -459,7 +458,7 @@ class iter_impl */ bool operator<=(const iter_impl& other) const { - return not other.operator < (*this); + return !other.operator < (*this); } /*! @@ -468,7 +467,7 @@ class iter_impl */ bool operator>(const iter_impl& other) const { - return not operator<=(other); + return !operator<=(other); } /*! @@ -477,7 +476,7 @@ class iter_impl */ bool operator>=(const iter_impl& other) const { - return not operator<(other); + return !operator<(other); } /*! diff --git a/include/nlohmann/detail/iterators/iteration_proxy.hpp b/include/nlohmann/detail/iterators/iteration_proxy.hpp index b10d0587b1..74b4eb347f 100644 --- a/include/nlohmann/detail/iterators/iteration_proxy.hpp +++ b/include/nlohmann/detail/iterators/iteration_proxy.hpp @@ -19,7 +19,7 @@ void int_to_string( string_type& target, std::size_t value ) using std::to_string; target = to_string(value); } -template class iteration_proxy_value +template class iteration_proxy_value { public: using difference_type = std::ptrdiff_t; @@ -133,7 +133,7 @@ template class iteration_proxy // Structured Bindings Support // For further reference see https://blog.tartanllama.xyz/structured-bindings/ // And see https://github.com/nlohmann/json/pull/1391 -template = 0> +template = 0> auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.key()) { return i.key(); @@ -141,7 +141,7 @@ auto get(const nlohmann::detail::iteration_proxy_value& i) -> decl // Structured Bindings Support // For further reference see https://blog.tartanllama.xyz/structured-bindings/ // And see https://github.com/nlohmann/json/pull/1391 -template = 0> +template = 0> auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.value()) { return i.value(); @@ -160,11 +160,11 @@ namespace std #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmismatched-tags" #endif -template +template class tuple_size<::nlohmann::detail::iteration_proxy_value> : public std::integral_constant {}; -template +template class tuple_element> { public: diff --git a/include/nlohmann/detail/iterators/iterator_traits.hpp b/include/nlohmann/detail/iterators/iterator_traits.hpp index 4cced80caf..da5636188f 100644 --- a/include/nlohmann/detail/iterators/iterator_traits.hpp +++ b/include/nlohmann/detail/iterators/iterator_traits.hpp @@ -9,10 +9,10 @@ namespace nlohmann { namespace detail { -template +template struct iterator_types {}; -template +template struct iterator_types < It, void_t +template struct iterator_traits { }; -template +template struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> : iterator_types { }; -template +template struct iterator_traits::value>> { using iterator_category = std::random_access_iterator_tag; diff --git a/include/nlohmann/detail/json_pointer.hpp b/include/nlohmann/detail/json_pointer.hpp index 1ac86591cf..78bc3a3a38 100644 --- a/include/nlohmann/detail/json_pointer.hpp +++ b/include/nlohmann/detail/json_pointer.hpp @@ -335,7 +335,7 @@ class json_pointer using size_type = typename BasicJsonType::size_type; // error condition (cf. RFC 6901, Sect. 4) - if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and s[0] == '0')) + if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0')) { JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + @@ -343,7 +343,7 @@ class json_pointer } // error condition (cf. RFC 6901, Sect. 4) - if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and not (s[0] >= '1' and s[0] <= '9'))) + if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9'))) { JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number")); } @@ -483,7 +483,7 @@ class json_pointer }); // change value to array for numbers or "-" or to object otherwise - *ptr = (nums or reference_token == "-") + *ptr = (nums || reference_token == "-") ? detail::value_t::array : detail::value_t::object; } @@ -665,7 +665,7 @@ class json_pointer { case detail::value_t::object: { - if (not ptr->contains(reference_token)) + if (!ptr->contains(reference_token)) { // we did not find the key in the object return false; @@ -682,21 +682,21 @@ class json_pointer // "-" always fails the range check return false; } - if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 and not ("0" <= reference_token and reference_token <= "9"))) + if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9"))) { // invalid char return false; } if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1)) { - if (JSON_HEDLEY_UNLIKELY(not ('1' <= reference_token[0] and reference_token[0] <= '9'))) + if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9'))) { // first char should be between '1' and '9' return false; } for (std::size_t i = 1; i < reference_token.size(); i++) { - if (JSON_HEDLEY_UNLIKELY(not ('0' <= reference_token[i] and reference_token[i] <= '9'))) + if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9'))) { // other char should be between '0' and '9' return false; @@ -783,8 +783,8 @@ class json_pointer JSON_ASSERT(reference_token[pos] == '~'); // ~ must be followed by 0 or 1 - if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or - (reference_token[pos + 1] != '0' and + if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 || + (reference_token[pos + 1] != '0' && reference_token[pos + 1] != '1'))) { JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'")); @@ -815,7 +815,7 @@ class json_pointer static void replace_substring(std::string& s, const std::string& f, const std::string& t) { - JSON_ASSERT(not f.empty()); + JSON_ASSERT(!f.empty()); for (auto pos = s.find(f); // find first occurrence of f pos != std::string::npos; // make sure f was found s.replace(pos, f.size(), t), // replace with t, and @@ -910,7 +910,7 @@ class json_pointer static BasicJsonType unflatten(const BasicJsonType& value) { - if (JSON_HEDLEY_UNLIKELY(not value.is_object())) + if (JSON_HEDLEY_UNLIKELY(!value.is_object())) { JSON_THROW(detail::type_error::create(314, "only objects can be unflattened")); } @@ -920,7 +920,7 @@ class json_pointer // iterate the JSON object values for (const auto& element : *value.m_value.object) { - if (JSON_HEDLEY_UNLIKELY(not element.second.is_primitive())) + if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive())) { JSON_THROW(detail::type_error::create(315, "values in object must be primitive")); } @@ -966,7 +966,7 @@ class json_pointer friend bool operator!=(json_pointer const& lhs, json_pointer const& rhs) noexcept { - return not (lhs == rhs); + return !(lhs == rhs); } /// the reference tokens diff --git a/include/nlohmann/detail/meta/cpp_future.hpp b/include/nlohmann/detail/meta/cpp_future.hpp index 11f88acc9d..dd929ee142 100644 --- a/include/nlohmann/detail/meta/cpp_future.hpp +++ b/include/nlohmann/detail/meta/cpp_future.hpp @@ -3,8 +3,6 @@ #include // size_t #include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type -#include - namespace nlohmann { namespace detail diff --git a/include/nlohmann/detail/meta/detected.hpp b/include/nlohmann/detail/meta/detected.hpp index e5ca5eb2e6..7b5a003537 100644 --- a/include/nlohmann/detail/meta/detected.hpp +++ b/include/nlohmann/detail/meta/detected.hpp @@ -19,39 +19,39 @@ struct nonesuch void operator=(nonesuch&&) = delete; }; -template class Op, - class... Args> +template class Op, + class... Args> struct detector { using value_t = std::false_type; using type = Default; }; -template class Op, class... Args> +template class Op, class... Args> struct detector>, Op, Args...> { using value_t = std::true_type; using type = Op; }; -template