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