mirror of
https://github.com/nlohmann/json.git
synced 2026-06-21 03:34:17 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| af3f87e84e | |||
| 286f0c7647 | |||
| d16f4496eb | |||
| e87dba5cc3 | |||
| 311ad0b877 |
+23
-10
@@ -1,4 +1,3 @@
|
|||||||
#AccessModifierOffset: 2
|
|
||||||
AlignAfterOpenBracket: Align
|
AlignAfterOpenBracket: Align
|
||||||
AlignConsecutiveAssignments: false
|
AlignConsecutiveAssignments: false
|
||||||
#AlignConsecutiveBitFields: false
|
#AlignConsecutiveBitFields: false
|
||||||
@@ -12,7 +11,7 @@ AllowAllConstructorInitializersOnNextLine: false
|
|||||||
AllowAllParametersOfDeclarationOnNextLine: false
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
AllowShortBlocksOnASingleLine: Empty
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
#AllowShortEnumsOnASingleLine: true
|
AllowShortEnumsOnASingleLine: true
|
||||||
AllowShortFunctionsOnASingleLine: Empty
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
AllowShortIfStatementsOnASingleLine: Never
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
AllowShortLambdasOnASingleLine: Empty
|
AllowShortLambdasOnASingleLine: Empty
|
||||||
@@ -30,27 +29,26 @@ BraceWrapping:
|
|||||||
AfterControlStatement: Always
|
AfterControlStatement: Always
|
||||||
AfterEnum: true
|
AfterEnum: true
|
||||||
AfterFunction: true
|
AfterFunction: true
|
||||||
AfterNamespace: false
|
AfterNamespace: true
|
||||||
AfterStruct: true
|
AfterStruct: true
|
||||||
AfterUnion: true
|
AfterUnion: true
|
||||||
AfterExternBlock: false
|
AfterExternBlock: false
|
||||||
BeforeCatch: true
|
BeforeCatch: true
|
||||||
BeforeElse: true
|
BeforeElse: true
|
||||||
#BeforeLambdaBody: false
|
BeforeLambdaBody: false
|
||||||
#BeforeWhile: false
|
BeforeWhile: false
|
||||||
SplitEmptyFunction: false
|
SplitEmptyFunction: false
|
||||||
SplitEmptyRecord: false
|
SplitEmptyRecord: false
|
||||||
SplitEmptyNamespace: false
|
SplitEmptyNamespace: false
|
||||||
BreakBeforeTernaryOperators: true
|
BreakBeforeTernaryOperators: true
|
||||||
BreakConstructorInitializers: BeforeComma
|
BreakConstructorInitializers: BeforeComma
|
||||||
BreakStringLiterals: false
|
BreakStringLiterals: false
|
||||||
ColumnLimit: 0
|
ColumnLimit: 160
|
||||||
CompactNamespaces: false
|
CompactNamespaces: false
|
||||||
ConstructorInitializerIndentWidth: 2
|
ConstructorInitializerIndentWidth: 2
|
||||||
Cpp11BracedListStyle: true
|
Cpp11BracedListStyle: false
|
||||||
PointerAlignment: Left
|
PointerAlignment: Left
|
||||||
FixNamespaceComments: true
|
FixNamespaceComments: true
|
||||||
IncludeBlocks: Preserve
|
|
||||||
#IndentCaseBlocks: false
|
#IndentCaseBlocks: false
|
||||||
IndentCaseLabels: true
|
IndentCaseLabels: true
|
||||||
IndentGotoLabels: false
|
IndentGotoLabels: false
|
||||||
@@ -60,7 +58,6 @@ KeepEmptyLinesAtTheStartOfBlocks: false
|
|||||||
MaxEmptyLinesToKeep: 1
|
MaxEmptyLinesToKeep: 1
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
ReflowComments: false
|
ReflowComments: false
|
||||||
SortIncludes: true
|
|
||||||
SortUsingDeclarations: true
|
SortUsingDeclarations: true
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
SpaceAfterLogicalNot: false
|
SpaceAfterLogicalNot: false
|
||||||
@@ -79,6 +76,22 @@ SpacesInConditionalStatement: false
|
|||||||
SpacesInContainerLiterals: false
|
SpacesInContainerLiterals: false
|
||||||
SpacesInParentheses: false
|
SpacesInParentheses: false
|
||||||
SpacesInSquareBrackets: false
|
SpacesInSquareBrackets: false
|
||||||
Standard: c++11
|
Standard: Latest
|
||||||
TabWidth: 4
|
TabWidth: 4
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
|
|
||||||
|
# what to do with include blocks
|
||||||
|
SortIncludes: true
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^".*"'
|
||||||
|
Priority: 1
|
||||||
|
- Regex: '<[^\/]+>'
|
||||||
|
Priority: 2
|
||||||
|
- Regex: '^<(nlohmann)\/-*'
|
||||||
|
Priority: 3
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 4
|
||||||
|
|
||||||
|
Macros:
|
||||||
|
- JSON_PRIVATE_UNLESS_TESTED=private
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ To make changes, you need to edit the following files:
|
|||||||
## Note
|
## Note
|
||||||
|
|
||||||
- If you open a pull request, the code will be automatically tested with [Valgrind](http://valgrind.org)'s Memcheck tool to detect memory leaks. Please be aware that the execution with Valgrind _may_ in rare cases yield different behavior than running the code directly. This can result in failing unit tests which run successfully without Valgrind.
|
- If you open a pull request, the code will be automatically tested with [Valgrind](http://valgrind.org)'s Memcheck tool to detect memory leaks. Please be aware that the execution with Valgrind _may_ in rare cases yield different behavior than running the code directly. This can result in failing unit tests which run successfully without Valgrind.
|
||||||
- There is a Makefile target `make pretty` which runs [Artistic Style](http://astyle.sourceforge.net) to fix indentation. If possible, run it before opening the pull request. Otherwise, we shall run it afterward.
|
- There is a Makefile target `make pretty` which runs [Clang-Format](https://clang.llvm.org/docs/ClangFormat.html) to fix indentation. If possible, run it before opening the pull request. Otherwise, we shall run it afterward.
|
||||||
|
|
||||||
## Please don't
|
## Please don't
|
||||||
|
|
||||||
|
|||||||
@@ -21,15 +21,9 @@ jobs:
|
|||||||
|
|
||||||
check:
|
check:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
container: silkeh/clang:dev
|
||||||
env:
|
env:
|
||||||
MAIN_DIR: ${{ github.workspace }}/main
|
MAIN_DIR: ${{ github.workspace }}/main
|
||||||
INCLUDE_DIR: ${{ github.workspace }}/main/single_include/nlohmann
|
|
||||||
TOOL_DIR: ${{ github.workspace }}/tools/tools/amalgamate
|
|
||||||
ASTYLE_FLAGS: >
|
|
||||||
--style=allman --indent=spaces=4 --indent-modifiers --indent-switches --indent-preproc-block
|
|
||||||
--indent-preproc-define --indent-col1-comments --pad-oper --pad-header --align-pointer=type
|
|
||||||
--align-reference=type --add-brackets --convert-tabs --close-templates --lineend=linux --preserve-date
|
|
||||||
--formatted
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout pull request
|
- name: Checkout pull request
|
||||||
@@ -44,27 +38,7 @@ jobs:
|
|||||||
path: tools
|
path: tools
|
||||||
ref: develop
|
ref: develop
|
||||||
|
|
||||||
- name: Install astyle
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install astyle
|
|
||||||
|
|
||||||
- name: Check amalgamation
|
- name: Check amalgamation
|
||||||
run: |
|
run: |
|
||||||
cd $MAIN_DIR
|
cd $MAIN_DIR
|
||||||
|
make check-amalgamation
|
||||||
rm -fr $INCLUDE_DIR/json.hpp~ $INCLUDE_DIR/json_fwd.hpp~
|
|
||||||
cp $INCLUDE_DIR/json.hpp $INCLUDE_DIR/json.hpp~
|
|
||||||
cp $INCLUDE_DIR/json_fwd.hpp $INCLUDE_DIR/json_fwd.hpp~
|
|
||||||
|
|
||||||
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json.json -s .
|
|
||||||
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json_fwd.json -s .
|
|
||||||
echo "Format (1)"
|
|
||||||
astyle $ASTYLE_FLAGS --suffix=none --quiet $INCLUDE_DIR/json.hpp $INCLUDE_DIR/json_fwd.hpp
|
|
||||||
|
|
||||||
diff $INCLUDE_DIR/json.hpp~ $INCLUDE_DIR/json.hpp
|
|
||||||
diff $INCLUDE_DIR/json_fwd.hpp~ $INCLUDE_DIR/json_fwd.hpp
|
|
||||||
|
|
||||||
astyle $ASTYLE_FLAGS $(find docs/examples include tests -type f \( -name '*.hpp' -o -name '*.cpp' -o -name '*.cu' \) -not -path 'tests/thirdparty/*' -not -path 'tests/abi/include/nlohmann/*' | sort)
|
|
||||||
echo Check
|
|
||||||
find $MAIN_DIR -name '*.orig' -exec false {} \+
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ jobs:
|
|||||||
container: ghcr.io/nlohmann/json-ci:v2.4.0
|
container: ghcr.io/nlohmann/json-ci:v2.4.0
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
target: [ci_cppcheck, ci_test_valgrind, ci_test_amalgamation, ci_test_single_header, ci_single_binaries, ci_infer]
|
target: [ci_cppcheck, ci_test_valgrind, ci_test_single_header, ci_single_binaries, ci_infer]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Run CMake
|
- name: Run CMake
|
||||||
@@ -54,6 +54,18 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build build --target ${{ matrix.target }}
|
run: cmake --build build --target ${{ matrix.target }}
|
||||||
|
|
||||||
|
ci_test_amalgamation:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: silkeh/clang:dev
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Get latest CMake and ninja
|
||||||
|
uses: lukka/get-cmake@v3.27.7
|
||||||
|
- name: Run CMake
|
||||||
|
run: cmake -S . -B build -DJSON_CI=On
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build --target ci_test_amalgamation
|
||||||
|
|
||||||
ci_static_analysis_ubuntu:
|
ci_static_analysis_ubuntu:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
|
|||||||
@@ -142,33 +142,9 @@ pvs_studio:
|
|||||||
# Code format and source amalgamation
|
# Code format and source amalgamation
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
# call the Artistic Style pretty printer on all source files
|
|
||||||
pretty:
|
|
||||||
astyle \
|
|
||||||
--style=allman \
|
|
||||||
--indent=spaces=4 \
|
|
||||||
--indent-modifiers \
|
|
||||||
--indent-switches \
|
|
||||||
--indent-preproc-block \
|
|
||||||
--indent-preproc-define \
|
|
||||||
--indent-col1-comments \
|
|
||||||
--pad-oper \
|
|
||||||
--pad-header \
|
|
||||||
--align-pointer=type \
|
|
||||||
--align-reference=type \
|
|
||||||
--add-braces \
|
|
||||||
--squeeze-lines=2 \
|
|
||||||
--convert-tabs \
|
|
||||||
--close-templates \
|
|
||||||
--lineend=linux \
|
|
||||||
--preserve-date \
|
|
||||||
--suffix=none \
|
|
||||||
--formatted \
|
|
||||||
$(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) docs/examples/*.cpp
|
|
||||||
|
|
||||||
# call the Clang-Format on all source files
|
# call the Clang-Format on all source files
|
||||||
pretty_format:
|
pretty:
|
||||||
for FILE in $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) docs/examples/*.cpp; do echo $$FILE; clang-format -i $$FILE; done
|
clang-format --Werror --verbose -i $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE)
|
||||||
|
|
||||||
# create single header files and pretty print
|
# create single header files and pretty print
|
||||||
amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE)
|
amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE)
|
||||||
|
|||||||
@@ -1774,8 +1774,8 @@ The library itself consists of a single header file licensed under the MIT licen
|
|||||||
- [**amalgamate.py - Amalgamate C source and header files**](https://github.com/edlund/amalgamate) to create a single header file
|
- [**amalgamate.py - Amalgamate C source and header files**](https://github.com/edlund/amalgamate) to create a single header file
|
||||||
- [**American fuzzy lop**](https://lcamtuf.coredump.cx/afl/) for fuzz testing
|
- [**American fuzzy lop**](https://lcamtuf.coredump.cx/afl/) for fuzz testing
|
||||||
- [**AppVeyor**](https://www.appveyor.com) for [continuous integration](https://ci.appveyor.com/project/nlohmann/json) on Windows
|
- [**AppVeyor**](https://www.appveyor.com) for [continuous integration](https://ci.appveyor.com/project/nlohmann/json) on Windows
|
||||||
- [**Artistic Style**](http://astyle.sourceforge.net) for automatic source code indentation
|
|
||||||
- [**Clang**](https://clang.llvm.org) for compilation with code sanitizers
|
- [**Clang**](https://clang.llvm.org) for compilation with code sanitizers
|
||||||
|
- [**Clang-Format**](https://clang.llvm.org/docs/ClangFormat.html) for automatic source code indentation
|
||||||
- [**CMake**](https://cmake.org) for build automation
|
- [**CMake**](https://cmake.org) for build automation
|
||||||
- [**Codacy**](https://www.codacy.com) for further [code analysis](https://www.codacy.com/app/nlohmann/json)
|
- [**Codacy**](https://www.codacy.com) for further [code analysis](https://www.codacy.com/app/nlohmann/json)
|
||||||
- [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json)
|
- [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json)
|
||||||
|
|||||||
+6
-31
@@ -8,16 +8,16 @@ set(N 10)
|
|||||||
include(FindPython3)
|
include(FindPython3)
|
||||||
find_package(Python3 COMPONENTS Interpreter)
|
find_package(Python3 COMPONENTS Interpreter)
|
||||||
|
|
||||||
find_program(ASTYLE_TOOL NAMES astyle)
|
|
||||||
execute_process(COMMAND ${ASTYLE_TOOL} --version OUTPUT_VARIABLE ASTYLE_TOOL_VERSION ERROR_VARIABLE ASTYLE_TOOL_VERSION)
|
|
||||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" ASTYLE_TOOL_VERSION "${ASTYLE_TOOL_VERSION}")
|
|
||||||
message(STATUS "🔖 Artistic Style ${ASTYLE_TOOL_VERSION} (${ASTYLE_TOOL})")
|
|
||||||
|
|
||||||
find_program(CLANG_TOOL NAMES clang++-HEAD clang++ clang++-17 clang++-16 clang++-15 clang++-14 clang++-13 clang++-12 clang++-11 clang++)
|
find_program(CLANG_TOOL NAMES clang++-HEAD clang++ clang++-17 clang++-16 clang++-15 clang++-14 clang++-13 clang++-12 clang++-11 clang++)
|
||||||
execute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION)
|
execute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION)
|
||||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TOOL_VERSION "${CLANG_TOOL_VERSION}")
|
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TOOL_VERSION "${CLANG_TOOL_VERSION}")
|
||||||
message(STATUS "🔖 Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})")
|
message(STATUS "🔖 Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})")
|
||||||
|
|
||||||
|
find_program(CLANG_FORMAT_TOOL NAMES clang-format)
|
||||||
|
execute_process(COMMAND ${CLANG_FORMAT_TOOL} --version OUTPUT_VARIABLE CLANG_FORMAT_TOOL_VERSION ERROR_VARIABLE CLANG_FORMAT_TOOL_VERSION)
|
||||||
|
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_FORMAT_TOOL_VERSION "${CLANG_FORMAT_TOOL_VERSION}")
|
||||||
|
message(STATUS "🔖 Clang-Format ${CLANG_FORMAT_TOOL_VERSION} (${CLANG_FORMAT_TOOL})")
|
||||||
|
|
||||||
find_program(CLANG_TIDY_TOOL NAMES clang-tidy-17 clang-tidy-16 clang-tidy-15 clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11 clang-tidy)
|
find_program(CLANG_TIDY_TOOL NAMES clang-tidy-17 clang-tidy-16 clang-tidy-15 clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11 clang-tidy)
|
||||||
execute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION)
|
execute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION)
|
||||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TIDY_TOOL_VERSION "${CLANG_TIDY_TOOL_VERSION}")
|
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TIDY_TOOL_VERSION "${CLANG_TIDY_TOOL_VERSION}")
|
||||||
@@ -581,33 +581,8 @@ add_custom_target(ci_test_clang_sanitizer
|
|||||||
# Check if header is amalgamated and sources are properly indented.
|
# Check if header is amalgamated and sources are properly indented.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
set(ASTYLE_FLAGS --style=allman --indent=spaces=4 --indent-modifiers --indent-switches --indent-preproc-block --indent-preproc-define --indent-col1-comments --pad-oper --pad-header --align-pointer=type --align-reference=type --add-brackets --convert-tabs --close-templates --lineend=linux --preserve-date --formatted)
|
|
||||||
|
|
||||||
file(GLOB_RECURSE INDENT_FILES
|
|
||||||
${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp
|
|
||||||
${PROJECT_SOURCE_DIR}/tests/src/*.cpp
|
|
||||||
${PROJECT_SOURCE_DIR}/tests/src/*.hpp
|
|
||||||
${PROJECT_SOURCE_DIR}/tests/benchmarks/src/benchmarks.cpp
|
|
||||||
${PROJECT_SOURCE_DIR}/docs/examples/*.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann)
|
|
||||||
set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate)
|
|
||||||
add_custom_target(ci_test_amalgamation
|
add_custom_target(ci_test_amalgamation
|
||||||
COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~
|
COMMAND make check-amalgamation
|
||||||
COMMAND cp ${include_dir}/json.hpp ${include_dir}/json.hpp~
|
|
||||||
COMMAND cp ${include_dir}/json_fwd.hpp ${include_dir}/json_fwd.hpp~
|
|
||||||
|
|
||||||
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json.json -s .
|
|
||||||
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_fwd.json -s .
|
|
||||||
COMMAND ${ASTYLE_TOOL} ${ASTYLE_FLAGS} --suffix=none --quiet ${include_dir}/json.hpp ${include_dir}/json_fwd.hpp
|
|
||||||
|
|
||||||
COMMAND diff ${include_dir}/json.hpp~ ${include_dir}/json.hpp
|
|
||||||
COMMAND diff ${include_dir}/json_fwd.hpp~ ${include_dir}/json_fwd.hpp
|
|
||||||
|
|
||||||
COMMAND ${ASTYLE_TOOL} ${ASTYLE_FLAGS} ${INDENT_FILES}
|
|
||||||
COMMAND for FILE in `find . -name '*.orig'`\; do false \; done
|
|
||||||
|
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
COMMENT "Check amalgamation and indentation"
|
COMMENT "Check amalgamation and indentation"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ struct adl_serializer
|
|||||||
/// @brief convert a JSON value to any value type
|
/// @brief convert a JSON value to any value type
|
||||||
/// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
|
/// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
|
||||||
template<typename BasicJsonType, typename TargetType = ValueType>
|
template<typename BasicJsonType, typename TargetType = ValueType>
|
||||||
static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
|
static auto from_json(BasicJsonType&& j, TargetType& val) noexcept(noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
|
||||||
noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
|
|
||||||
-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
|
-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
|
||||||
{
|
{
|
||||||
::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
|
::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
|
||||||
@@ -34,8 +33,7 @@ struct adl_serializer
|
|||||||
/// @brief convert a JSON value to any value type
|
/// @brief convert a JSON value to any value type
|
||||||
/// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
|
/// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
|
||||||
template<typename BasicJsonType, typename TargetType = ValueType>
|
template<typename BasicJsonType, typename TargetType = ValueType>
|
||||||
static auto from_json(BasicJsonType && j) noexcept(
|
static auto from_json(BasicJsonType&& j) noexcept(noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType>{})))
|
||||||
noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
|
|
||||||
-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType>{}))
|
-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType>{}))
|
||||||
{
|
{
|
||||||
return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType>{});
|
return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType>{});
|
||||||
@@ -44,8 +42,7 @@ struct adl_serializer
|
|||||||
/// @brief convert any value type to a JSON value
|
/// @brief convert any value type to a JSON value
|
||||||
/// @sa https://json.nlohmann.me/api/adl_serializer/to_json/
|
/// @sa https://json.nlohmann.me/api/adl_serializer/to_json/
|
||||||
template<typename BasicJsonType, typename TargetType = ValueType>
|
template<typename BasicJsonType, typename TargetType = ValueType>
|
||||||
static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
|
static auto to_json(BasicJsonType& j, TargetType&& val) noexcept(noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
|
||||||
noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
|
|
||||||
-> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
|
-> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
|
||||||
{
|
{
|
||||||
::nlohmann::to_json(j, std::forward<TargetType>(val));
|
::nlohmann::to_json(j, std::forward<TargetType>(val));
|
||||||
|
|||||||
@@ -48,48 +48,34 @@
|
|||||||
|
|
||||||
// Construct the namespace ABI tags component
|
// Construct the namespace ABI tags component
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi##a##b
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi##a##b
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
|
|
||||||
|
|
||||||
#define NLOHMANN_JSON_ABI_TAGS \
|
#define NLOHMANN_JSON_ABI_TAGS NLOHMANN_JSON_ABI_TAGS_CONCAT(NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
|
||||||
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
|
|
||||||
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
|
|
||||||
|
|
||||||
// Construct the namespace version component
|
// Construct the namespace version component
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) _v##major##_##minor##_##patch
|
||||||
_v ## major ## _ ## minor ## _ ## patch
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
|
|
||||||
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
|
|
||||||
|
|
||||||
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION
|
#define NLOHMANN_JSON_NAMESPACE_VERSION
|
||||||
#else
|
#else
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION \
|
#define NLOHMANN_JSON_NAMESPACE_VERSION \
|
||||||
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
|
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH)
|
||||||
NLOHMANN_JSON_VERSION_MINOR, \
|
|
||||||
NLOHMANN_JSON_VERSION_PATCH)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Combine namespace components
|
// Combine namespace components
|
||||||
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a##b
|
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a##b
|
||||||
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
|
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
|
||||||
NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
|
|
||||||
|
|
||||||
#ifndef NLOHMANN_JSON_NAMESPACE
|
#ifndef NLOHMANN_JSON_NAMESPACE
|
||||||
#define NLOHMANN_JSON_NAMESPACE \
|
#define NLOHMANN_JSON_NAMESPACE nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT(NLOHMANN_JSON_ABI_TAGS, NLOHMANN_JSON_NAMESPACE_VERSION)
|
||||||
nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
|
|
||||||
NLOHMANN_JSON_ABI_TAGS, \
|
|
||||||
NLOHMANN_JSON_NAMESPACE_VERSION)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
|
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
|
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
|
||||||
namespace nlohmann \
|
namespace nlohmann \
|
||||||
{ \
|
{ \
|
||||||
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
|
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT(NLOHMANN_JSON_ABI_TAGS, NLOHMANN_JSON_NAMESPACE_VERSION) \
|
||||||
NLOHMANN_JSON_ABI_TAGS, \
|
|
||||||
NLOHMANN_JSON_NAMESPACE_VERSION) \
|
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -44,10 +44,9 @@ inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// overloads for basic_json template parameters
|
// overloads for basic_json template parameters
|
||||||
template < typename BasicJsonType, typename ArithmeticType,
|
template<typename BasicJsonType,
|
||||||
enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
|
typename ArithmeticType,
|
||||||
!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
|
enable_if_t<std::is_arithmetic<ArithmeticType>::value && !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value, int> = 0>
|
||||||
int > = 0 >
|
|
||||||
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
|
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
|
||||||
{
|
{
|
||||||
switch (static_cast<value_t>(j))
|
switch (static_cast<value_t>(j))
|
||||||
@@ -100,13 +99,12 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t&
|
|||||||
s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template<typename BasicJsonType,
|
||||||
typename BasicJsonType, typename StringType,
|
typename StringType,
|
||||||
enable_if_t <
|
enable_if_t<std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value &&
|
||||||
std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
|
is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value &&
|
||||||
&& is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value
|
!std::is_same<typename BasicJsonType::string_t, StringType>::value && !is_json_ref<StringType>::value,
|
||||||
&& !std::is_same<typename BasicJsonType::string_t, StringType>::value
|
int> = 0>
|
||||||
&& !is_json_ref<StringType>::value, int > = 0 >
|
|
||||||
inline void from_json(const BasicJsonType& j, StringType& s)
|
inline void from_json(const BasicJsonType& j, StringType& s)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
|
||||||
@@ -136,8 +134,7 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_int
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !JSON_DISABLE_ENUM_SERIALIZATION
|
#if !JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
template<typename BasicJsonType, typename EnumType,
|
template<typename BasicJsonType, typename EnumType, enable_if_t<std::is_enum<EnumType>::value, int> = 0>
|
||||||
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
|
|
||||||
inline void from_json(const BasicJsonType& j, EnumType& e)
|
inline void from_json(const BasicJsonType& j, EnumType& e)
|
||||||
{
|
{
|
||||||
typename std::underlying_type<EnumType>::type val;
|
typename std::underlying_type<EnumType>::type val;
|
||||||
@@ -147,8 +144,7 @@ inline void from_json(const BasicJsonType& j, EnumType& e)
|
|||||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
|
|
||||||
// forward_list doesn't have an insert method
|
// forward_list doesn't have an insert method
|
||||||
template<typename BasicJsonType, typename T, typename Allocator,
|
template<typename BasicJsonType, typename T, typename Allocator, enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
|
||||||
enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
|
|
||||||
inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
|
inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||||
@@ -156,16 +152,13 @@ inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l
|
|||||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||||
}
|
}
|
||||||
l.clear();
|
l.clear();
|
||||||
std::transform(j.rbegin(), j.rend(),
|
std::transform(j.rbegin(), j.rend(), std::front_inserter(l), [](const BasicJsonType& i) {
|
||||||
std::front_inserter(l), [](const BasicJsonType & i)
|
|
||||||
{
|
|
||||||
return i.template get<T>();
|
return i.template get<T>();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// valarray doesn't have an insert method
|
// valarray doesn't have an insert method
|
||||||
template<typename BasicJsonType, typename T,
|
template<typename BasicJsonType, typename T, enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
|
||||||
enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
|
|
||||||
inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
|
inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||||
@@ -173,9 +166,7 @@ inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
|
|||||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||||
}
|
}
|
||||||
l.resize(j.size());
|
l.resize(j.size());
|
||||||
std::transform(j.begin(), j.end(), std::begin(l),
|
std::transform(j.begin(), j.end(), std::begin(l), [](const BasicJsonType& elem) {
|
||||||
[](const BasicJsonType & elem)
|
|
||||||
{
|
|
||||||
return elem.template get<T>();
|
return elem.template get<T>();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -197,9 +188,7 @@ inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T, std::size_t N>
|
template<typename BasicJsonType, typename T, std::size_t N>
|
||||||
auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
|
auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> /*unused*/) -> decltype(j.template get<T>(), void())
|
||||||
priority_tag<2> /*unused*/)
|
|
||||||
-> decltype(j.template get<T>(), void())
|
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < N; ++i)
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
@@ -207,23 +196,17 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleArrayType,
|
template<typename BasicJsonType,
|
||||||
enable_if_t<
|
typename ConstructibleArrayType,
|
||||||
std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
|
enable_if_t<std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value, int> = 0>
|
||||||
int> = 0>
|
|
||||||
auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
|
auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
|
||||||
-> decltype(
|
-> decltype(arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()), j.template get<typename ConstructibleArrayType::value_type>(), void())
|
||||||
arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
|
|
||||||
j.template get<typename ConstructibleArrayType::value_type>(),
|
|
||||||
void())
|
|
||||||
{
|
{
|
||||||
using std::end;
|
using std::end;
|
||||||
|
|
||||||
ConstructibleArrayType ret;
|
ConstructibleArrayType ret;
|
||||||
ret.reserve(j.size());
|
ret.reserve(j.size());
|
||||||
std::transform(j.begin(), j.end(),
|
std::transform(j.begin(), j.end(), std::inserter(ret, end(ret)), [](const BasicJsonType& i) {
|
||||||
std::inserter(ret, end(ret)), [](const BasicJsonType & i)
|
|
||||||
{
|
|
||||||
// get<BasicJsonType>() returns *this, this won't call a from_json
|
// get<BasicJsonType>() returns *this, this won't call a from_json
|
||||||
// method when value_type is BasicJsonType
|
// method when value_type is BasicJsonType
|
||||||
return i.template get<typename ConstructibleArrayType::value_type>();
|
return i.template get<typename ConstructibleArrayType::value_type>();
|
||||||
@@ -231,20 +214,15 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p
|
|||||||
arr = std::move(ret);
|
arr = std::move(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleArrayType,
|
template<typename BasicJsonType,
|
||||||
enable_if_t<
|
typename ConstructibleArrayType,
|
||||||
std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
|
enable_if_t<std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value, int> = 0>
|
||||||
int> = 0>
|
inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<0> /*unused*/)
|
||||||
inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
|
|
||||||
priority_tag<0> /*unused*/)
|
|
||||||
{
|
{
|
||||||
using std::end;
|
using std::end;
|
||||||
|
|
||||||
ConstructibleArrayType ret;
|
ConstructibleArrayType ret;
|
||||||
std::transform(
|
std::transform(j.begin(), j.end(), std::inserter(ret, end(ret)), [](const BasicJsonType& i) {
|
||||||
j.begin(), j.end(), std::inserter(ret, end(ret)),
|
|
||||||
[](const BasicJsonType & i)
|
|
||||||
{
|
|
||||||
// get<BasicJsonType>() returns *this, this won't call a from_json
|
// get<BasicJsonType>() returns *this, this won't call a from_json
|
||||||
// method when value_type is BasicJsonType
|
// method when value_type is BasicJsonType
|
||||||
return i.template get<typename ConstructibleArrayType::value_type>();
|
return i.template get<typename ConstructibleArrayType::value_type>();
|
||||||
@@ -252,18 +230,15 @@ inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType&
|
|||||||
arr = std::move(ret);
|
arr = std::move(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename ConstructibleArrayType,
|
template<typename BasicJsonType,
|
||||||
enable_if_t <
|
typename ConstructibleArrayType,
|
||||||
is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
|
enable_if_t<is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value &&
|
||||||
!is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value &&
|
!is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value &&
|
||||||
!is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value &&
|
!is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value &&
|
||||||
!std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
|
!std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value && !is_basic_json<ConstructibleArrayType>::value,
|
||||||
!is_basic_json<ConstructibleArrayType>::value,
|
|
||||||
int> = 0>
|
int> = 0>
|
||||||
auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
|
auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
|
||||||
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
|
-> decltype(from_json_array_impl(j, arr, priority_tag<3>{}), j.template get<typename ConstructibleArrayType::value_type>(), void())
|
||||||
j.template get<typename ConstructibleArrayType::value_type>(),
|
|
||||||
void())
|
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||||
{
|
{
|
||||||
@@ -274,8 +249,8 @@ void())
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T, std::size_t... Idx>
|
template<typename BasicJsonType, typename T, std::size_t... Idx>
|
||||||
std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
|
std::array<T, sizeof...(Idx)>
|
||||||
identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
|
from_json_inplace_array_impl(BasicJsonType&& j, identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
|
||||||
{
|
{
|
||||||
return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
|
return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
|
||||||
}
|
}
|
||||||
@@ -303,7 +278,8 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t&
|
|||||||
bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
|
bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleObjectType,
|
template<typename BasicJsonType,
|
||||||
|
typename ConstructibleObjectType,
|
||||||
enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
|
enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
|
||||||
inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
||||||
{
|
{
|
||||||
@@ -315,11 +291,7 @@ inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
|||||||
ConstructibleObjectType ret;
|
ConstructibleObjectType ret;
|
||||||
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
||||||
using value_type = typename ConstructibleObjectType::value_type;
|
using value_type = typename ConstructibleObjectType::value_type;
|
||||||
std::transform(
|
std::transform(inner_object->begin(), inner_object->end(), std::inserter(ret, ret.begin()), [](typename BasicJsonType::object_t::value_type const& p) {
|
||||||
inner_object->begin(), inner_object->end(),
|
|
||||||
std::inserter(ret, ret.begin()),
|
|
||||||
[](typename BasicJsonType::object_t::value_type const & p)
|
|
||||||
{
|
|
||||||
return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
|
return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
|
||||||
});
|
});
|
||||||
obj = std::move(ret);
|
obj = std::move(ret);
|
||||||
@@ -329,10 +301,9 @@ inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
|||||||
// (BooleanType, etc..); note: Is it really necessary to provide explicit
|
// (BooleanType, etc..); note: Is it really necessary to provide explicit
|
||||||
// overloads for boolean_t etc. in case of a custom BooleanType which is not
|
// overloads for boolean_t etc. in case of a custom BooleanType which is not
|
||||||
// an arithmetic type?
|
// an arithmetic type?
|
||||||
template < typename BasicJsonType, typename ArithmeticType,
|
template<typename BasicJsonType,
|
||||||
enable_if_t <
|
typename ArithmeticType,
|
||||||
std::is_arithmetic<ArithmeticType>::value&&
|
enable_if_t<std::is_arithmetic<ArithmeticType>::value && !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value &&
|
||||||
!std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
|
|
||||||
!std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value &&
|
!std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value &&
|
||||||
!std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value &&
|
!std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value &&
|
||||||
!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
|
!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
|
||||||
@@ -382,8 +353,7 @@ std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<
|
|||||||
template<typename BasicJsonType, class A1, class A2>
|
template<typename BasicJsonType, class A1, class A2>
|
||||||
std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
|
std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
|
||||||
{
|
{
|
||||||
return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
|
return { std::forward<BasicJsonType>(j).at(0).template get<A1>(), std::forward<BasicJsonType>(j).at(1).template get<A2>() };
|
||||||
std::forward<BasicJsonType>(j).at(1).template get<A2>()};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename A1, typename A2>
|
template<typename BasicJsonType, typename A1, typename A2>
|
||||||
@@ -416,9 +386,12 @@ auto from_json(BasicJsonType&& j, TupleRelated&& t)
|
|||||||
return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3>{});
|
return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
|
template<typename BasicJsonType,
|
||||||
typename = enable_if_t < !std::is_constructible <
|
typename Key,
|
||||||
typename BasicJsonType::string_t, Key >::value >>
|
typename Value,
|
||||||
|
typename Compare,
|
||||||
|
typename Allocator,
|
||||||
|
typename = enable_if_t<!std::is_constructible<typename BasicJsonType::string_t, Key>::value>>
|
||||||
inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
|
inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||||
@@ -436,9 +409,13 @@ inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
|
template<typename BasicJsonType,
|
||||||
typename = enable_if_t < !std::is_constructible <
|
typename Key,
|
||||||
typename BasicJsonType::string_t, Key >::value >>
|
typename Value,
|
||||||
|
typename Hash,
|
||||||
|
typename KeyEqual,
|
||||||
|
typename Allocator,
|
||||||
|
typename = enable_if_t<!std::is_constructible<typename BasicJsonType::string_t, Key>::value>>
|
||||||
inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
|
inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||||
@@ -471,8 +448,7 @@ inline void from_json(const BasicJsonType& j, std_fs::path& p)
|
|||||||
struct from_json_fn
|
struct from_json_fn
|
||||||
{
|
{
|
||||||
template<typename BasicJsonType, typename T>
|
template<typename BasicJsonType, typename T>
|
||||||
auto operator()(const BasicJsonType& j, T&& val) const
|
auto operator()(const BasicJsonType& j, T&& val) const noexcept(noexcept(from_json(j, std::forward<T>(val))))
|
||||||
noexcept(noexcept(from_json(j, std::forward<T>(val))))
|
|
||||||
-> decltype(from_json(j, std::forward<T>(val)))
|
-> decltype(from_json(j, std::forward<T>(val)))
|
||||||
{
|
{
|
||||||
return from_json(j, std::forward<T>(val));
|
return from_json(j, std::forward<T>(val));
|
||||||
|
|||||||
@@ -61,7 +61,10 @@ struct diyfp // f * 2^e
|
|||||||
std::uint64_t f = 0;
|
std::uint64_t f = 0;
|
||||||
int e = 0;
|
int e = 0;
|
||||||
|
|
||||||
constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
|
constexpr diyfp(std::uint64_t f_, int e_) noexcept
|
||||||
|
: f(f_)
|
||||||
|
, e(e_)
|
||||||
|
{}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief returns x - y
|
@brief returns x - y
|
||||||
@@ -198,8 +201,7 @@ boundaries compute_boundaries(FloatType value)
|
|||||||
// If v is normalized:
|
// If v is normalized:
|
||||||
// value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
|
// value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
|
||||||
|
|
||||||
static_assert(std::numeric_limits<FloatType>::is_iec559,
|
static_assert(std::numeric_limits<FloatType>::is_iec559, "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
|
||||||
"internal error: dtoa_short requires an IEEE-754 floating-point implementation");
|
|
||||||
|
|
||||||
constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
|
constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
|
||||||
constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
|
constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
|
||||||
@@ -213,9 +215,7 @@ boundaries compute_boundaries(FloatType value)
|
|||||||
const std::uint64_t F = bits & (kHiddenBit - 1);
|
const std::uint64_t F = bits & (kHiddenBit - 1);
|
||||||
|
|
||||||
const bool is_denormal = E == 0;
|
const bool is_denormal = E == 0;
|
||||||
const diyfp v = is_denormal
|
const diyfp v = is_denormal ? diyfp(F, kMinExp) : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
|
||||||
? diyfp(F, kMinExp)
|
|
||||||
: diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
|
|
||||||
|
|
||||||
// Compute the boundaries m- and m+ of the floating-point value
|
// Compute the boundaries m- and m+ of the floating-point value
|
||||||
// v = f * 2^e.
|
// v = f * 2^e.
|
||||||
@@ -240,8 +240,7 @@ boundaries compute_boundaries(FloatType value)
|
|||||||
|
|
||||||
const bool lower_boundary_is_closer = F == 0 && 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_plus = diyfp(2 * v.f + 1, v.e - 1);
|
||||||
const diyfp m_minus = lower_boundary_is_closer
|
const diyfp m_minus = lower_boundary_is_closer ? diyfp(4 * v.f - 1, v.e - 2) // (B)
|
||||||
? diyfp(4 * v.f - 1, v.e - 2) // (B)
|
|
||||||
: diyfp(2 * v.f - 1, v.e - 1); // (A)
|
: diyfp(2 * v.f - 1, v.e - 1); // (A)
|
||||||
|
|
||||||
// Determine the normalized w+ = m+.
|
// Determine the normalized w+ = m+.
|
||||||
@@ -380,90 +379,28 @@ inline cached_power get_cached_power_for_binary_exponent(int e)
|
|||||||
constexpr int kCachedPowersMinDecExp = -300;
|
constexpr int kCachedPowersMinDecExp = -300;
|
||||||
constexpr int kCachedPowersDecStep = 8;
|
constexpr int kCachedPowersDecStep = 8;
|
||||||
|
|
||||||
static constexpr std::array<cached_power, 79> kCachedPowers =
|
static constexpr std::array<cached_power, 79> kCachedPowers = { {
|
||||||
{
|
{ 0xAB70FE17C79AC6CA, -1060, -300 }, { 0xFF77B1FCBEBCDC4F, -1034, -292 }, { 0xBE5691EF416BD60C, -1007, -284 }, { 0x8DD01FAD907FFC3C, -980, -276 },
|
||||||
{
|
{ 0xD3515C2831559A83, -954, -268 }, { 0x9D71AC8FADA6C9B5, -927, -260 }, { 0xEA9C227723EE8BCB, -901, -252 }, { 0xAECC49914078536D, -874, -244 },
|
||||||
{ 0xAB70FE17C79AC6CA, -1060, -300 },
|
{ 0x823C12795DB6CE57, -847, -236 }, { 0xC21094364DFB5637, -821, -228 }, { 0x9096EA6F3848984F, -794, -220 }, { 0xD77485CB25823AC7, -768, -212 },
|
||||||
{ 0xFF77B1FCBEBCDC4F, -1034, -292 },
|
{ 0xA086CFCD97BF97F4, -741, -204 }, { 0xEF340A98172AACE5, -715, -196 }, { 0xB23867FB2A35B28E, -688, -188 }, { 0x84C8D4DFD2C63F3B, -661, -180 },
|
||||||
{ 0xBE5691EF416BD60C, -1007, -284 },
|
{ 0xC5DD44271AD3CDBA, -635, -172 }, { 0x936B9FCEBB25C996, -608, -164 }, { 0xDBAC6C247D62A584, -582, -156 }, { 0xA3AB66580D5FDAF6, -555, -148 },
|
||||||
{ 0x8DD01FAD907FFC3C, -980, -276 },
|
{ 0xF3E2F893DEC3F126, -529, -140 }, { 0xB5B5ADA8AAFF80B8, -502, -132 }, { 0x87625F056C7C4A8B, -475, -124 }, { 0xC9BCFF6034C13053, -449, -116 },
|
||||||
{ 0xD3515C2831559A83, -954, -268 },
|
{ 0x964E858C91BA2655, -422, -108 }, { 0xDFF9772470297EBD, -396, -100 }, { 0xA6DFBD9FB8E5B88F, -369, -92 }, { 0xF8A95FCF88747D94, -343, -84 },
|
||||||
{ 0x9D71AC8FADA6C9B5, -927, -260 },
|
{ 0xB94470938FA89BCF, -316, -76 }, { 0x8A08F0F8BF0F156B, -289, -68 }, { 0xCDB02555653131B6, -263, -60 }, { 0x993FE2C6D07B7FAC, -236, -52 },
|
||||||
{ 0xEA9C227723EE8BCB, -901, -252 },
|
{ 0xE45C10C42A2B3B06, -210, -44 }, { 0xAA242499697392D3, -183, -36 }, { 0xFD87B5F28300CA0E, -157, -28 }, { 0xBCE5086492111AEB, -130, -20 },
|
||||||
{ 0xAECC49914078536D, -874, -244 },
|
{ 0x8CBCCC096F5088CC, -103, -12 }, { 0xD1B71758E219652C, -77, -4 }, { 0x9C40000000000000, -50, 4 }, { 0xE8D4A51000000000, -24, 12 },
|
||||||
{ 0x823C12795DB6CE57, -847, -236 },
|
{ 0xAD78EBC5AC620000, 3, 20 }, { 0x813F3978F8940984, 30, 28 }, { 0xC097CE7BC90715B3, 56, 36 }, { 0x8F7E32CE7BEA5C70, 83, 44 },
|
||||||
{ 0xC21094364DFB5637, -821, -228 },
|
{ 0xD5D238A4ABE98068, 109, 52 }, { 0x9F4F2726179A2245, 136, 60 }, { 0xED63A231D4C4FB27, 162, 68 }, { 0xB0DE65388CC8ADA8, 189, 76 },
|
||||||
{ 0x9096EA6F3848984F, -794, -220 },
|
{ 0x83C7088E1AAB65DB, 216, 84 }, { 0xC45D1DF942711D9A, 242, 92 }, { 0x924D692CA61BE758, 269, 100 }, { 0xDA01EE641A708DEA, 295, 108 },
|
||||||
{ 0xD77485CB25823AC7, -768, -212 },
|
{ 0xA26DA3999AEF774A, 322, 116 }, { 0xF209787BB47D6B85, 348, 124 }, { 0xB454E4A179DD1877, 375, 132 }, { 0x865B86925B9BC5C2, 402, 140 },
|
||||||
{ 0xA086CFCD97BF97F4, -741, -204 },
|
{ 0xC83553C5C8965D3D, 428, 148 }, { 0x952AB45CFA97A0B3, 455, 156 }, { 0xDE469FBD99A05FE3, 481, 164 }, { 0xA59BC234DB398C25, 508, 172 },
|
||||||
{ 0xEF340A98172AACE5, -715, -196 },
|
{ 0xF6C69A72A3989F5C, 534, 180 }, { 0xB7DCBF5354E9BECE, 561, 188 }, { 0x88FCF317F22241E2, 588, 196 }, { 0xCC20CE9BD35C78A5, 614, 204 },
|
||||||
{ 0xB23867FB2A35B28E, -688, -188 },
|
{ 0x98165AF37B2153DF, 641, 212 }, { 0xE2A0B5DC971F303A, 667, 220 }, { 0xA8D9D1535CE3B396, 694, 228 }, { 0xFB9B7CD9A4A7443C, 720, 236 },
|
||||||
{ 0x84C8D4DFD2C63F3B, -661, -180 },
|
{ 0xBB764C4CA7A44410, 747, 244 }, { 0x8BAB8EEFB6409C1A, 774, 252 }, { 0xD01FEF10A657842C, 800, 260 }, { 0x9B10A4E5E9913129, 827, 268 },
|
||||||
{ 0xC5DD44271AD3CDBA, -635, -172 },
|
{ 0xE7109BFBA19C0C9D, 853, 276 }, { 0xAC2820D9623BF429, 880, 284 }, { 0x80444B5E7AA7CF85, 907, 292 }, { 0xBF21E44003ACDD2D, 933, 300 },
|
||||||
{ 0x936B9FCEBB25C996, -608, -164 },
|
{ 0x8E679C2F5E44FF8F, 960, 308 }, { 0xD433179D9C8CB841, 986, 316 }, { 0x9E19DB92B4E31BA9, 1013, 324 },
|
||||||
{ 0xDBAC6C247D62A584, -582, -156 },
|
} };
|
||||||
{ 0xA3AB66580D5FDAF6, -555, -148 },
|
|
||||||
{ 0xF3E2F893DEC3F126, -529, -140 },
|
|
||||||
{ 0xB5B5ADA8AAFF80B8, -502, -132 },
|
|
||||||
{ 0x87625F056C7C4A8B, -475, -124 },
|
|
||||||
{ 0xC9BCFF6034C13053, -449, -116 },
|
|
||||||
{ 0x964E858C91BA2655, -422, -108 },
|
|
||||||
{ 0xDFF9772470297EBD, -396, -100 },
|
|
||||||
{ 0xA6DFBD9FB8E5B88F, -369, -92 },
|
|
||||||
{ 0xF8A95FCF88747D94, -343, -84 },
|
|
||||||
{ 0xB94470938FA89BCF, -316, -76 },
|
|
||||||
{ 0x8A08F0F8BF0F156B, -289, -68 },
|
|
||||||
{ 0xCDB02555653131B6, -263, -60 },
|
|
||||||
{ 0x993FE2C6D07B7FAC, -236, -52 },
|
|
||||||
{ 0xE45C10C42A2B3B06, -210, -44 },
|
|
||||||
{ 0xAA242499697392D3, -183, -36 },
|
|
||||||
{ 0xFD87B5F28300CA0E, -157, -28 },
|
|
||||||
{ 0xBCE5086492111AEB, -130, -20 },
|
|
||||||
{ 0x8CBCCC096F5088CC, -103, -12 },
|
|
||||||
{ 0xD1B71758E219652C, -77, -4 },
|
|
||||||
{ 0x9C40000000000000, -50, 4 },
|
|
||||||
{ 0xE8D4A51000000000, -24, 12 },
|
|
||||||
{ 0xAD78EBC5AC620000, 3, 20 },
|
|
||||||
{ 0x813F3978F8940984, 30, 28 },
|
|
||||||
{ 0xC097CE7BC90715B3, 56, 36 },
|
|
||||||
{ 0x8F7E32CE7BEA5C70, 83, 44 },
|
|
||||||
{ 0xD5D238A4ABE98068, 109, 52 },
|
|
||||||
{ 0x9F4F2726179A2245, 136, 60 },
|
|
||||||
{ 0xED63A231D4C4FB27, 162, 68 },
|
|
||||||
{ 0xB0DE65388CC8ADA8, 189, 76 },
|
|
||||||
{ 0x83C7088E1AAB65DB, 216, 84 },
|
|
||||||
{ 0xC45D1DF942711D9A, 242, 92 },
|
|
||||||
{ 0x924D692CA61BE758, 269, 100 },
|
|
||||||
{ 0xDA01EE641A708DEA, 295, 108 },
|
|
||||||
{ 0xA26DA3999AEF774A, 322, 116 },
|
|
||||||
{ 0xF209787BB47D6B85, 348, 124 },
|
|
||||||
{ 0xB454E4A179DD1877, 375, 132 },
|
|
||||||
{ 0x865B86925B9BC5C2, 402, 140 },
|
|
||||||
{ 0xC83553C5C8965D3D, 428, 148 },
|
|
||||||
{ 0x952AB45CFA97A0B3, 455, 156 },
|
|
||||||
{ 0xDE469FBD99A05FE3, 481, 164 },
|
|
||||||
{ 0xA59BC234DB398C25, 508, 172 },
|
|
||||||
{ 0xF6C69A72A3989F5C, 534, 180 },
|
|
||||||
{ 0xB7DCBF5354E9BECE, 561, 188 },
|
|
||||||
{ 0x88FCF317F22241E2, 588, 196 },
|
|
||||||
{ 0xCC20CE9BD35C78A5, 614, 204 },
|
|
||||||
{ 0x98165AF37B2153DF, 641, 212 },
|
|
||||||
{ 0xE2A0B5DC971F303A, 667, 220 },
|
|
||||||
{ 0xA8D9D1535CE3B396, 694, 228 },
|
|
||||||
{ 0xFB9B7CD9A4A7443C, 720, 236 },
|
|
||||||
{ 0xBB764C4CA7A44410, 747, 244 },
|
|
||||||
{ 0x8BAB8EEFB6409C1A, 774, 252 },
|
|
||||||
{ 0xD01FEF10A657842C, 800, 260 },
|
|
||||||
{ 0x9B10A4E5E9913129, 827, 268 },
|
|
||||||
{ 0xE7109BFBA19C0C9D, 853, 276 },
|
|
||||||
{ 0xAC2820D9623BF429, 880, 284 },
|
|
||||||
{ 0x80444B5E7AA7CF85, 907, 292 },
|
|
||||||
{ 0xBF21E44003ACDD2D, 933, 300 },
|
|
||||||
{ 0x8E679C2F5E44FF8F, 960, 308 },
|
|
||||||
{ 0xD433179D9C8CB841, 986, 316 },
|
|
||||||
{ 0x9E19DB92B4E31BA9, 1013, 324 },
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// This computation gives exactly the same results for k as
|
// This computation gives exactly the same results for k as
|
||||||
// k = ceil((kAlpha - e - 1) * 0.30102999566398114)
|
// k = ceil((kAlpha - e - 1) * 0.30102999566398114)
|
||||||
@@ -543,8 +480,7 @@ inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
|
inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
|
||||||
std::uint64_t rest, std::uint64_t ten_k)
|
|
||||||
{
|
{
|
||||||
JSON_ASSERT(len >= 1);
|
JSON_ASSERT(len >= 1);
|
||||||
JSON_ASSERT(dist <= delta);
|
JSON_ASSERT(dist <= delta);
|
||||||
@@ -570,9 +506,7 @@ inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t d
|
|||||||
// The tests are written in this order to avoid overflow in unsigned
|
// The tests are written in this order to avoid overflow in unsigned
|
||||||
// integer arithmetic.
|
// integer arithmetic.
|
||||||
|
|
||||||
while (rest < dist
|
while (rest < dist && delta - rest >= ten_k && (rest + ten_k < dist || 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');
|
JSON_ASSERT(buf[len - 1] != '0');
|
||||||
buf[len - 1]--;
|
buf[len - 1]--;
|
||||||
@@ -584,8 +518,7 @@ inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t d
|
|||||||
Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
|
Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
|
||||||
M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
|
M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
|
||||||
*/
|
*/
|
||||||
inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
|
inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
|
||||||
diyfp M_minus, diyfp w, diyfp M_plus)
|
|
||||||
{
|
{
|
||||||
static_assert(kAlpha >= -60, "internal error");
|
static_assert(kAlpha >= -60, "internal error");
|
||||||
static_assert(kGamma <= -32, "internal error");
|
static_assert(kGamma <= -32, "internal error");
|
||||||
@@ -825,8 +758,7 @@ len is the length of the buffer (number of decimal digits)
|
|||||||
The buffer must be large enough, i.e. >= max_digits10.
|
The buffer must be large enough, i.e. >= max_digits10.
|
||||||
*/
|
*/
|
||||||
JSON_HEDLEY_NON_NULL(1)
|
JSON_HEDLEY_NON_NULL(1)
|
||||||
inline void grisu2(char* buf, int& len, int& decimal_exponent,
|
inline void grisu2(char* buf, int& len, int& decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
|
||||||
diyfp m_minus, diyfp v, diyfp m_plus)
|
|
||||||
{
|
{
|
||||||
JSON_ASSERT(m_plus.e == m_minus.e);
|
JSON_ASSERT(m_plus.e == m_minus.e);
|
||||||
JSON_ASSERT(m_plus.e == v.e);
|
JSON_ASSERT(m_plus.e == v.e);
|
||||||
@@ -887,8 +819,7 @@ template<typename FloatType>
|
|||||||
JSON_HEDLEY_NON_NULL(1)
|
JSON_HEDLEY_NON_NULL(1)
|
||||||
void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
|
void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
|
||||||
{
|
{
|
||||||
static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
|
static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3, "internal error: not enough precision");
|
||||||
"internal error: not enough precision");
|
|
||||||
|
|
||||||
JSON_ASSERT(std::isfinite(value));
|
JSON_ASSERT(std::isfinite(value));
|
||||||
JSON_ASSERT(value > 0);
|
JSON_ASSERT(value > 0);
|
||||||
@@ -977,8 +908,7 @@ notation. Otherwise it will be printed in exponential notation.
|
|||||||
*/
|
*/
|
||||||
JSON_HEDLEY_NON_NULL(1)
|
JSON_HEDLEY_NON_NULL(1)
|
||||||
JSON_HEDLEY_RETURNS_NON_NULL
|
JSON_HEDLEY_RETURNS_NON_NULL
|
||||||
inline char* format_buffer(char* buf, int len, int decimal_exponent,
|
inline char* format_buffer(char* buf, int len, int decimal_exponent, int min_exp, int max_exp)
|
||||||
int min_exp, int max_exp)
|
|
||||||
{
|
{
|
||||||
JSON_ASSERT(min_exp < 0);
|
JSON_ASSERT(min_exp < 0);
|
||||||
JSON_ASSERT(max_exp > 0);
|
JSON_ASSERT(max_exp > 0);
|
||||||
@@ -1061,8 +991,7 @@ format. Returns an iterator pointing past-the-end of the decimal representation.
|
|||||||
*/
|
*/
|
||||||
template<typename FloatType>
|
template<typename FloatType>
|
||||||
JSON_HEDLEY_NON_NULL(1, 2)
|
JSON_HEDLEY_NON_NULL(1, 2)
|
||||||
JSON_HEDLEY_RETURNS_NON_NULL
|
JSON_HEDLEY_RETURNS_NON_NULL char* to_chars(char* first, const char* last, FloatType value)
|
||||||
char* to_chars(char* first, const char* last, FloatType value)
|
|
||||||
{
|
{
|
||||||
static_cast<void>(last); // maybe unused - fix warning
|
static_cast<void>(last); // maybe unused - fix warning
|
||||||
JSON_ASSERT(std::isfinite(value));
|
JSON_ASSERT(std::isfinite(value));
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ namespace detail
|
|||||||
* https://github.com/nlohmann/json/issues/2865 for more information.
|
* https://github.com/nlohmann/json/issues/2865 for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<value_t> struct external_constructor;
|
template<value_t>
|
||||||
|
struct external_constructor;
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct external_constructor<value_t::boolean>
|
struct external_constructor<value_t::boolean>
|
||||||
@@ -75,9 +76,9 @@ struct external_constructor<value_t::string>
|
|||||||
j.assert_invariant();
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename CompatibleStringType,
|
template<typename BasicJsonType,
|
||||||
enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
|
typename CompatibleStringType,
|
||||||
int > = 0 >
|
enable_if_t<!std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value, int> = 0>
|
||||||
static void construct(BasicJsonType& j, const CompatibleStringType& str)
|
static void construct(BasicJsonType& j, const CompatibleStringType& str)
|
||||||
{
|
{
|
||||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
@@ -171,9 +172,9 @@ struct external_constructor<value_t::array>
|
|||||||
j.assert_invariant();
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename CompatibleArrayType,
|
template<typename BasicJsonType,
|
||||||
enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
|
typename CompatibleArrayType,
|
||||||
int > = 0 >
|
enable_if_t<!std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value, int> = 0>
|
||||||
static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
|
static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
|
||||||
{
|
{
|
||||||
using std::begin;
|
using std::begin;
|
||||||
@@ -201,8 +202,7 @@ struct external_constructor<value_t::array>
|
|||||||
j.assert_invariant();
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T,
|
template<typename BasicJsonType, typename T, enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
|
||||||
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
|
|
||||||
static void construct(BasicJsonType& j, const std::valarray<T>& arr)
|
static void construct(BasicJsonType& j, const std::valarray<T>& arr)
|
||||||
{
|
{
|
||||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||||
@@ -241,7 +241,8 @@ struct external_constructor<value_t::object>
|
|||||||
j.assert_invariant();
|
j.assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename CompatibleObjectType,
|
template<typename BasicJsonType,
|
||||||
|
typename CompatibleObjectType,
|
||||||
enable_if_t<!std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
|
enable_if_t<!std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
|
||||||
static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
|
static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
|
||||||
{
|
{
|
||||||
@@ -260,27 +261,27 @@ struct external_constructor<value_t::object>
|
|||||||
// to_json //
|
// to_json //
|
||||||
/////////////
|
/////////////
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T,
|
template<typename BasicJsonType, typename T, enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
|
||||||
enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
|
|
||||||
inline void to_json(BasicJsonType& j, T b) noexcept
|
inline void to_json(BasicJsonType& j, T b) noexcept
|
||||||
{
|
{
|
||||||
external_constructor<value_t::boolean>::construct(j, b);
|
external_constructor<value_t::boolean>::construct(j, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename BoolRef,
|
template<typename BasicJsonType,
|
||||||
enable_if_t <
|
typename BoolRef,
|
||||||
((std::is_same<std::vector<bool>::reference, BoolRef>::value
|
enable_if_t<((std::is_same<std::vector<bool>::reference, BoolRef>::value &&
|
||||||
&& !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
|
!std::is_same<std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value) ||
|
||||||
|| (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
|
(std::is_same<std::vector<bool>::const_reference, BoolRef>::value &&
|
||||||
&& !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
|
!std::is_same<detail::uncvref_t<std::vector<bool>::const_reference>, typename BasicJsonType::boolean_t>::value)) &&
|
||||||
typename BasicJsonType::boolean_t >::value))
|
std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value,
|
||||||
&& std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 >
|
int> = 0>
|
||||||
inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
|
inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
|
||||||
{
|
{
|
||||||
external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
|
external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleString,
|
template<typename BasicJsonType,
|
||||||
|
typename CompatibleString,
|
||||||
enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
|
enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
|
||||||
inline void to_json(BasicJsonType& j, const CompatibleString& s)
|
inline void to_json(BasicJsonType& j, const CompatibleString& s)
|
||||||
{
|
{
|
||||||
@@ -293,21 +294,22 @@ inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
|
|||||||
external_constructor<value_t::string>::construct(j, std::move(s));
|
external_constructor<value_t::string>::construct(j, std::move(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename FloatType,
|
template<typename BasicJsonType, typename FloatType, enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
|
||||||
enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
|
|
||||||
inline void to_json(BasicJsonType& j, FloatType val) noexcept
|
inline void to_json(BasicJsonType& j, FloatType val) noexcept
|
||||||
{
|
{
|
||||||
external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
|
external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
|
template<typename BasicJsonType,
|
||||||
|
typename CompatibleNumberUnsignedType,
|
||||||
enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
|
enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
|
||||||
inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
|
inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
|
||||||
{
|
{
|
||||||
external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
|
external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleNumberIntegerType,
|
template<typename BasicJsonType,
|
||||||
|
typename CompatibleNumberIntegerType,
|
||||||
enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
|
enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
|
||||||
inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
|
inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
|
||||||
{
|
{
|
||||||
@@ -315,8 +317,7 @@ inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !JSON_DISABLE_ENUM_SERIALIZATION
|
#if !JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
template<typename BasicJsonType, typename EnumType,
|
template<typename BasicJsonType, typename EnumType, enable_if_t<std::is_enum<EnumType>::value, int> = 0>
|
||||||
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
|
|
||||||
inline void to_json(BasicJsonType& j, EnumType e) noexcept
|
inline void to_json(BasicJsonType& j, EnumType e) noexcept
|
||||||
{
|
{
|
||||||
using underlying_type = typename std::underlying_type<EnumType>::type;
|
using underlying_type = typename std::underlying_type<EnumType>::type;
|
||||||
@@ -330,13 +331,12 @@ inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
|
|||||||
external_constructor<value_t::array>::construct(j, e);
|
external_constructor<value_t::array>::construct(j, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename CompatibleArrayType,
|
template<
|
||||||
enable_if_t < is_compatible_array_type<BasicJsonType,
|
typename BasicJsonType,
|
||||||
CompatibleArrayType>::value&&
|
typename CompatibleArrayType,
|
||||||
!is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
|
enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value && !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value &&
|
||||||
!is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value &&
|
!is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value &&
|
||||||
!std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
|
!std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value && !is_basic_json<CompatibleArrayType>::value,
|
||||||
!is_basic_json<CompatibleArrayType>::value,
|
|
||||||
int> = 0>
|
int> = 0>
|
||||||
inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
|
inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
|
||||||
{
|
{
|
||||||
@@ -349,8 +349,7 @@ inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bi
|
|||||||
external_constructor<value_t::binary>::construct(j, bin);
|
external_constructor<value_t::binary>::construct(j, bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T,
|
template<typename BasicJsonType, typename T, enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
|
||||||
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
|
|
||||||
inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
|
inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
|
||||||
{
|
{
|
||||||
external_constructor<value_t::array>::construct(j, std::move(arr));
|
external_constructor<value_t::array>::construct(j, std::move(arr));
|
||||||
@@ -362,7 +361,8 @@ inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
|
|||||||
external_constructor<value_t::array>::construct(j, std::move(arr));
|
external_constructor<value_t::array>::construct(j, std::move(arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename CompatibleObjectType,
|
template<typename BasicJsonType,
|
||||||
|
typename CompatibleObjectType,
|
||||||
enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value && !is_basic_json<CompatibleObjectType>::value, int> = 0>
|
enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value && !is_basic_json<CompatibleObjectType>::value, int> = 0>
|
||||||
inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
|
inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
|
||||||
{
|
{
|
||||||
@@ -375,8 +375,9 @@ inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
|||||||
external_constructor<value_t::object>::construct(j, std::move(obj));
|
external_constructor<value_t::object>::construct(j, std::move(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template<typename BasicJsonType,
|
||||||
typename BasicJsonType, typename T, std::size_t N,
|
typename T,
|
||||||
|
std::size_t N,
|
||||||
enable_if_t<!std::is_constructible<typename BasicJsonType::string_t,
|
enable_if_t<!std::is_constructible<typename BasicJsonType::string_t,
|
||||||
const T (&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
const T (&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||||
int> = 0>
|
int> = 0>
|
||||||
@@ -385,15 +386,17 @@ inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguideli
|
|||||||
external_constructor<value_t::array>::construct(j, arr);
|
external_constructor<value_t::array>::construct(j, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
|
template<typename BasicJsonType,
|
||||||
|
typename T1,
|
||||||
|
typename T2,
|
||||||
|
enable_if_t<std::is_constructible<BasicJsonType, T1>::value && std::is_constructible<BasicJsonType, T2>::value, int> = 0>
|
||||||
inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
|
inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
|
||||||
{
|
{
|
||||||
j = { p.first, p.second };
|
j = { p.first, p.second };
|
||||||
}
|
}
|
||||||
|
|
||||||
// for https://github.com/nlohmann/json/pull/1134
|
// for https://github.com/nlohmann/json/pull/1134
|
||||||
template<typename BasicJsonType, typename T,
|
template<typename BasicJsonType, typename T, enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
|
||||||
enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
|
|
||||||
inline void to_json(BasicJsonType& j, const T& b)
|
inline void to_json(BasicJsonType& j, const T& b)
|
||||||
{
|
{
|
||||||
j = { { b.key(), b.value() } };
|
j = { { b.key(), b.value() } };
|
||||||
@@ -422,8 +425,7 @@ inline void to_json(BasicJsonType& j, const std_fs::path& p)
|
|||||||
struct to_json_fn
|
struct to_json_fn
|
||||||
{
|
{
|
||||||
template<typename BasicJsonType, typename T>
|
template<typename BasicJsonType, typename T>
|
||||||
auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
|
auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val)))) -> decltype(to_json(j, std::forward<T>(val)), void())
|
||||||
-> decltype(to_json(j, std::forward<T>(val)), void())
|
|
||||||
{
|
{
|
||||||
return to_json(j, std::forward<T>(val));
|
return to_json(j, std::forward<T>(val));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,13 @@
|
|||||||
#include <string> // to_string
|
#include <string> // to_string
|
||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
|
|
||||||
#include <nlohmann/detail/value_t.hpp>
|
|
||||||
#include <nlohmann/detail/string_escape.hpp>
|
|
||||||
#include <nlohmann/detail/input/position_t.hpp>
|
#include <nlohmann/detail/input/position_t.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
#include <nlohmann/detail/meta/cpp_future.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
#include <nlohmann/detail/meta/type_traits.hpp>
|
#include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
#include <nlohmann/detail/string_concat.hpp>
|
#include <nlohmann/detail/string_concat.hpp>
|
||||||
|
#include <nlohmann/detail/string_escape.hpp>
|
||||||
|
#include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
namespace detail
|
namespace detail
|
||||||
@@ -49,7 +49,10 @@ class exception : public std::exception
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
JSON_HEDLEY_NON_NULL(3)
|
JSON_HEDLEY_NON_NULL(3)
|
||||||
exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
|
exception(int id_, const char* what_arg)
|
||||||
|
: id(id_)
|
||||||
|
, m(what_arg) // NOLINT(bugprone-throw-keyword-missing)
|
||||||
|
{}
|
||||||
|
|
||||||
static std::string name(const std::string& ename, int id_)
|
static std::string name(const std::string& ename, int id_)
|
||||||
{
|
{
|
||||||
@@ -114,9 +117,7 @@ class exception : public std::exception
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
|
auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, [](const std::string& a, const std::string& b) {
|
||||||
[](const std::string & a, const std::string & b)
|
|
||||||
{
|
|
||||||
return concat(a, '/', detail::escape(b));
|
return concat(a, '/', detail::escape(b));
|
||||||
});
|
});
|
||||||
return concat('(', str, ") ");
|
return concat('(', str, ") ");
|
||||||
@@ -148,17 +149,19 @@ class parse_error : public exception
|
|||||||
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
|
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
|
||||||
static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
|
static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
|
||||||
{
|
{
|
||||||
const std::string w = concat(exception::name("parse_error", id_), "parse error",
|
const std::string w = concat(exception::name("parse_error", id_), "parse error", position_string(pos), ": ", exception::diagnostics(context), what_arg);
|
||||||
position_string(pos), ": ", exception::diagnostics(context), what_arg);
|
|
||||||
return { id_, pos.chars_read_total, w.c_str() };
|
return { id_, pos.chars_read_total, w.c_str() };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
|
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
|
||||||
static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
|
static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
|
||||||
{
|
{
|
||||||
const std::string w = concat(exception::name("parse_error", id_), "parse error",
|
const std::string w = concat(exception::name("parse_error", id_),
|
||||||
|
"parse error",
|
||||||
(byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
|
(byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
|
||||||
": ", exception::diagnostics(context), what_arg);
|
": ",
|
||||||
|
exception::diagnostics(context),
|
||||||
|
what_arg);
|
||||||
return { id_, byte_, w.c_str() };
|
return { id_, byte_, w.c_str() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,12 +178,13 @@ class parse_error : public exception
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
parse_error(int id_, std::size_t byte_, const char* what_arg)
|
parse_error(int id_, std::size_t byte_, const char* what_arg)
|
||||||
: exception(id_, what_arg), byte(byte_) {}
|
: exception(id_, what_arg)
|
||||||
|
, byte(byte_)
|
||||||
|
{}
|
||||||
|
|
||||||
static std::string position_string(const position_t& pos)
|
static std::string position_string(const position_t& pos)
|
||||||
{
|
{
|
||||||
return concat(" at line ", std::to_string(pos.lines_read + 1),
|
return concat(" at line ", std::to_string(pos.lines_read + 1), ", column ", std::to_string(pos.chars_read_current_line));
|
||||||
", column ", std::to_string(pos.chars_read_current_line));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -199,7 +203,8 @@ class invalid_iterator : public exception
|
|||||||
private:
|
private:
|
||||||
JSON_HEDLEY_NON_NULL(3)
|
JSON_HEDLEY_NON_NULL(3)
|
||||||
invalid_iterator(int id_, const char* what_arg)
|
invalid_iterator(int id_, const char* what_arg)
|
||||||
: exception(id_, what_arg) {}
|
: exception(id_, what_arg)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief exception indicating executing a member function with a wrong type
|
/// @brief exception indicating executing a member function with a wrong type
|
||||||
@@ -216,7 +221,9 @@ class type_error : public exception
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
JSON_HEDLEY_NON_NULL(3)
|
JSON_HEDLEY_NON_NULL(3)
|
||||||
type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
|
type_error(int id_, const char* what_arg)
|
||||||
|
: exception(id_, what_arg)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief exception indicating access out of the defined range
|
/// @brief exception indicating access out of the defined range
|
||||||
@@ -233,7 +240,9 @@ class out_of_range : public exception
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
JSON_HEDLEY_NON_NULL(3)
|
JSON_HEDLEY_NON_NULL(3)
|
||||||
out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
|
out_of_range(int id_, const char* what_arg)
|
||||||
|
: exception(id_, what_arg)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief exception indicating other library errors
|
/// @brief exception indicating other library errors
|
||||||
@@ -250,7 +259,9 @@ class other_error : public exception
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
JSON_HEDLEY_NON_NULL(3)
|
JSON_HEDLEY_NON_NULL(3)
|
||||||
other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
|
other_error(int id_, const char* what_arg)
|
||||||
|
: exception(id_, what_arg)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint> // uint8_t
|
|
||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
|
#include <cstdint> // uint8_t
|
||||||
#include <functional> // hash
|
#include <functional> // hash
|
||||||
|
|
||||||
#include <nlohmann/detail/abi_macros.hpp>
|
#include <nlohmann/detail/abi_macros.hpp>
|
||||||
|
|||||||
@@ -80,7 +80,9 @@ class binary_reader
|
|||||||
|
|
||||||
@param[in] adapter input adapter to read from
|
@param[in] adapter input adapter to read from
|
||||||
*/
|
*/
|
||||||
explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
|
explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept
|
||||||
|
: ia(std::move(adapter))
|
||||||
|
, input_format(format)
|
||||||
{
|
{
|
||||||
(void)detail::is_sax_static_asserts<SAX, BasicJsonType>{};
|
(void)detail::is_sax_static_asserts<SAX, BasicJsonType>{};
|
||||||
}
|
}
|
||||||
@@ -101,10 +103,7 @@ class binary_reader
|
|||||||
@return whether parsing was successful
|
@return whether parsing was successful
|
||||||
*/
|
*/
|
||||||
JSON_HEDLEY_NON_NULL(3)
|
JSON_HEDLEY_NON_NULL(3)
|
||||||
bool sax_parse(const input_format_t format,
|
bool sax_parse(const input_format_t format, json_sax_t* sax_, const bool strict = true, const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
|
||||||
json_sax_t* sax_,
|
|
||||||
const bool strict = true,
|
|
||||||
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
|
|
||||||
{
|
{
|
||||||
sax = sax_;
|
sax = sax_;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@@ -147,8 +146,13 @@ class binary_reader
|
|||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(current != char_traits<char_type>::eof()))
|
if (JSON_HEDLEY_UNLIKELY(current != char_traits<char_type>::eof()))
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
|
chars_read,
|
||||||
|
get_token_string(),
|
||||||
|
parse_error::create(110,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,8 +228,13 @@ class binary_reader
|
|||||||
if (JSON_HEDLEY_UNLIKELY(len < 1))
|
if (JSON_HEDLEY_UNLIKELY(len < 1))
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(112,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != char_traits<char_type>::eof();
|
return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != char_traits<char_type>::eof();
|
||||||
@@ -246,8 +255,13 @@ class binary_reader
|
|||||||
if (JSON_HEDLEY_UNLIKELY(len < 0))
|
if (JSON_HEDLEY_UNLIKELY(len < 0))
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(112,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// All BSON binary values have a subtype
|
// All BSON binary values have a subtype
|
||||||
@@ -268,8 +282,7 @@ class binary_reader
|
|||||||
Unsupported BSON record type 0x...
|
Unsupported BSON record type 0x...
|
||||||
@return whether a valid BSON-object/array was passed to the SAX parser
|
@return whether a valid BSON-object/array was passed to the SAX parser
|
||||||
*/
|
*/
|
||||||
bool parse_bson_element_internal(const char_int_type element_type,
|
bool parse_bson_element_internal(const char_int_type element_type, const std::size_t element_type_parse_position)
|
||||||
const std::size_t element_type_parse_position)
|
|
||||||
{
|
{
|
||||||
switch (element_type)
|
switch (element_type)
|
||||||
{
|
{
|
||||||
@@ -328,9 +341,13 @@ class binary_reader
|
|||||||
default: // anything else not supported (yet)
|
default: // anything else not supported (yet)
|
||||||
{
|
{
|
||||||
std::array<char, 3> cr{ {} };
|
std::array<char, 3> cr{ {} };
|
||||||
static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
static_cast<void>((std::snprintf)(cr.data(), // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
|
cr.size(),
|
||||||
|
"%.2hhX",
|
||||||
|
static_cast<unsigned char>(element_type)));
|
||||||
const std::string cr_str{ cr.data() };
|
const std::string cr_str{ cr.data() };
|
||||||
return sax->parse_error(element_type_parse_position, cr_str,
|
return sax->parse_error(element_type_parse_position,
|
||||||
|
cr_str,
|
||||||
parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
|
parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -416,8 +433,7 @@ class binary_reader
|
|||||||
|
|
||||||
@return whether a valid CBOR value was passed to the SAX parser
|
@return whether a valid CBOR value was passed to the SAX parser
|
||||||
*/
|
*/
|
||||||
bool parse_cbor_internal(const bool get_char,
|
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
|
||||||
const cbor_tag_handler_t tag_handler)
|
|
||||||
{
|
{
|
||||||
switch (get_char ? get() : current)
|
switch (get_char ? get() : current)
|
||||||
{
|
{
|
||||||
@@ -524,8 +540,8 @@ class binary_reader
|
|||||||
case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
|
case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
|
||||||
{
|
{
|
||||||
std::uint64_t number{};
|
std::uint64_t number{};
|
||||||
return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
|
return get_number(input_format_t::cbor, number) &&
|
||||||
- static_cast<number_integer_t>(number));
|
sax->number_integer(static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(number));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Binary data (0x00..0x17 bytes follow)
|
// Binary data (0x00..0x17 bytes follow)
|
||||||
@@ -623,8 +639,7 @@ class binary_reader
|
|||||||
case 0x95:
|
case 0x95:
|
||||||
case 0x96:
|
case 0x96:
|
||||||
case 0x97:
|
case 0x97:
|
||||||
return get_cbor_array(
|
return get_cbor_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
|
||||||
conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
|
|
||||||
|
|
||||||
case 0x98: // array (one-byte uint8_t for n follows)
|
case 0x98: // array (one-byte uint8_t for n follows)
|
||||||
{
|
{
|
||||||
@@ -732,8 +747,12 @@ class binary_reader
|
|||||||
case cbor_tag_handler_t::error:
|
case cbor_tag_handler_t::error:
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
|
return sax->parse_error(chars_read,
|
||||||
exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
|
last_token,
|
||||||
|
parse_error::create(112,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
case cbor_tag_handler_t::ignore:
|
case cbor_tag_handler_t::ignore:
|
||||||
@@ -852,8 +871,7 @@ class binary_reader
|
|||||||
// half-precision floating-point numbers in the C language
|
// half-precision floating-point numbers in the C language
|
||||||
// is shown in Fig. 3.
|
// is shown in Fig. 3.
|
||||||
const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
|
const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
|
||||||
const double val = [&half]
|
const double val = [&half] {
|
||||||
{
|
|
||||||
const int exp = (half >> 10u) & 0x1Fu;
|
const int exp = (half >> 10u) & 0x1Fu;
|
||||||
const unsigned int mant = half & 0x3FFu;
|
const unsigned int mant = half & 0x3FFu;
|
||||||
JSON_ASSERT(0 <= exp && exp <= 32);
|
JSON_ASSERT(0 <= exp && exp <= 32);
|
||||||
@@ -863,16 +881,12 @@ class binary_reader
|
|||||||
case 0:
|
case 0:
|
||||||
return std::ldexp(mant, -24);
|
return std::ldexp(mant, -24);
|
||||||
case 31:
|
case 31:
|
||||||
return (mant == 0)
|
return (mant == 0) ? std::numeric_limits<double>::infinity() : std::numeric_limits<double>::quiet_NaN();
|
||||||
? std::numeric_limits<double>::infinity()
|
|
||||||
: std::numeric_limits<double>::quiet_NaN();
|
|
||||||
default:
|
default:
|
||||||
return std::ldexp(mant + 1024, exp - 25);
|
return std::ldexp(mant + 1024, exp - 25);
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
return sax->number_float((half & 0x8000u) != 0
|
return sax->number_float((half & 0x8000u) != 0 ? static_cast<number_float_t>(-val) : static_cast<number_float_t>(val), "");
|
||||||
? static_cast<number_float_t>(-val)
|
|
||||||
: static_cast<number_float_t>(val), "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xFA: // Single-Precision Float (four-byte IEEE 754)
|
case 0xFA: // Single-Precision Float (four-byte IEEE 754)
|
||||||
@@ -890,8 +904,10 @@ class binary_reader
|
|||||||
default: // anything else (0xFF is handled inside the other types)
|
default: // anything else (0xFF is handled inside the other types)
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(112, chars_read, exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -986,8 +1002,16 @@ class binary_reader
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(
|
||||||
|
113,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format_t::cbor,
|
||||||
|
concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token),
|
||||||
|
"string"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1044,29 +1068,25 @@ class binary_reader
|
|||||||
case 0x58: // Binary data (one-byte uint8_t for n follows)
|
case 0x58: // Binary data (one-byte uint8_t for n follows)
|
||||||
{
|
{
|
||||||
std::uint8_t len{};
|
std::uint8_t len{};
|
||||||
return get_number(input_format_t::cbor, len) &&
|
return get_number(input_format_t::cbor, len) && get_binary(input_format_t::cbor, len, result);
|
||||||
get_binary(input_format_t::cbor, len, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x59: // Binary data (two-byte uint16_t for n follow)
|
case 0x59: // Binary data (two-byte uint16_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint16_t len{};
|
std::uint16_t len{};
|
||||||
return get_number(input_format_t::cbor, len) &&
|
return get_number(input_format_t::cbor, len) && get_binary(input_format_t::cbor, len, result);
|
||||||
get_binary(input_format_t::cbor, len, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x5A: // Binary data (four-byte uint32_t for n follow)
|
case 0x5A: // Binary data (four-byte uint32_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint32_t len{};
|
std::uint32_t len{};
|
||||||
return get_number(input_format_t::cbor, len) &&
|
return get_number(input_format_t::cbor, len) && get_binary(input_format_t::cbor, len, result);
|
||||||
get_binary(input_format_t::cbor, len, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x5B: // Binary data (eight-byte uint64_t for n follow)
|
case 0x5B: // Binary data (eight-byte uint64_t for n follow)
|
||||||
{
|
{
|
||||||
std::uint64_t len{};
|
std::uint64_t len{};
|
||||||
return get_number(input_format_t::cbor, len) &&
|
return get_number(input_format_t::cbor, len) && get_binary(input_format_t::cbor, len, result);
|
||||||
get_binary(input_format_t::cbor, len, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x5F: // Binary data (indefinite length)
|
case 0x5F: // Binary data (indefinite length)
|
||||||
@@ -1086,8 +1106,16 @@ class binary_reader
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(
|
||||||
|
113,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format_t::cbor,
|
||||||
|
concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token),
|
||||||
|
"binary"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1098,8 +1126,7 @@ class binary_reader
|
|||||||
@param[in] tag_handler how CBOR tags should be treated
|
@param[in] tag_handler how CBOR tags should be treated
|
||||||
@return whether array creation completed
|
@return whether array creation completed
|
||||||
*/
|
*/
|
||||||
bool get_cbor_array(const std::size_t len,
|
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
|
||||||
const cbor_tag_handler_t tag_handler)
|
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
|
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
|
||||||
{
|
{
|
||||||
@@ -1136,8 +1163,7 @@ class binary_reader
|
|||||||
@param[in] tag_handler how CBOR tags should be treated
|
@param[in] tag_handler how CBOR tags should be treated
|
||||||
@return whether object creation completed
|
@return whether object creation completed
|
||||||
*/
|
*/
|
||||||
bool get_cbor_object(const std::size_t len,
|
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
|
||||||
const cbor_tag_handler_t tag_handler)
|
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
|
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
|
||||||
{
|
{
|
||||||
@@ -1557,8 +1583,10 @@ class binary_reader
|
|||||||
default: // anything else
|
default: // anything else
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1640,8 +1668,15 @@ class binary_reader
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(113,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format_t::msgpack,
|
||||||
|
concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token),
|
||||||
|
"string"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1659,8 +1694,7 @@ class binary_reader
|
|||||||
bool get_msgpack_binary(binary_t& result)
|
bool get_msgpack_binary(binary_t& result)
|
||||||
{
|
{
|
||||||
// helper function to set the subtype
|
// helper function to set the subtype
|
||||||
auto assign_and_return_true = [&result](std::int8_t subtype)
|
auto assign_and_return_true = [&result](std::int8_t subtype) {
|
||||||
{
|
|
||||||
result.set_subtype(static_cast<std::uint8_t>(subtype));
|
result.set_subtype(static_cast<std::uint8_t>(subtype));
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -1670,92 +1704,73 @@ class binary_reader
|
|||||||
case 0xC4: // bin 8
|
case 0xC4: // bin 8
|
||||||
{
|
{
|
||||||
std::uint8_t len{};
|
std::uint8_t len{};
|
||||||
return get_number(input_format_t::msgpack, len) &&
|
return get_number(input_format_t::msgpack, len) && get_binary(input_format_t::msgpack, len, result);
|
||||||
get_binary(input_format_t::msgpack, len, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xC5: // bin 16
|
case 0xC5: // bin 16
|
||||||
{
|
{
|
||||||
std::uint16_t len{};
|
std::uint16_t len{};
|
||||||
return get_number(input_format_t::msgpack, len) &&
|
return get_number(input_format_t::msgpack, len) && get_binary(input_format_t::msgpack, len, result);
|
||||||
get_binary(input_format_t::msgpack, len, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xC6: // bin 32
|
case 0xC6: // bin 32
|
||||||
{
|
{
|
||||||
std::uint32_t len{};
|
std::uint32_t len{};
|
||||||
return get_number(input_format_t::msgpack, len) &&
|
return get_number(input_format_t::msgpack, len) && get_binary(input_format_t::msgpack, len, result);
|
||||||
get_binary(input_format_t::msgpack, len, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xC7: // ext 8
|
case 0xC7: // ext 8
|
||||||
{
|
{
|
||||||
std::uint8_t len{};
|
std::uint8_t len{};
|
||||||
std::int8_t subtype{};
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, len) &&
|
return get_number(input_format_t::msgpack, len) && get_number(input_format_t::msgpack, subtype) &&
|
||||||
get_number(input_format_t::msgpack, subtype) &&
|
get_binary(input_format_t::msgpack, len, result) && assign_and_return_true(subtype);
|
||||||
get_binary(input_format_t::msgpack, len, result) &&
|
|
||||||
assign_and_return_true(subtype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xC8: // ext 16
|
case 0xC8: // ext 16
|
||||||
{
|
{
|
||||||
std::uint16_t len{};
|
std::uint16_t len{};
|
||||||
std::int8_t subtype{};
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, len) &&
|
return get_number(input_format_t::msgpack, len) && get_number(input_format_t::msgpack, subtype) &&
|
||||||
get_number(input_format_t::msgpack, subtype) &&
|
get_binary(input_format_t::msgpack, len, result) && assign_and_return_true(subtype);
|
||||||
get_binary(input_format_t::msgpack, len, result) &&
|
|
||||||
assign_and_return_true(subtype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xC9: // ext 32
|
case 0xC9: // ext 32
|
||||||
{
|
{
|
||||||
std::uint32_t len{};
|
std::uint32_t len{};
|
||||||
std::int8_t subtype{};
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, len) &&
|
return get_number(input_format_t::msgpack, len) && get_number(input_format_t::msgpack, subtype) &&
|
||||||
get_number(input_format_t::msgpack, subtype) &&
|
get_binary(input_format_t::msgpack, len, result) && assign_and_return_true(subtype);
|
||||||
get_binary(input_format_t::msgpack, len, result) &&
|
|
||||||
assign_and_return_true(subtype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD4: // fixext 1
|
case 0xD4: // fixext 1
|
||||||
{
|
{
|
||||||
std::int8_t subtype{};
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, subtype) &&
|
return get_number(input_format_t::msgpack, subtype) && get_binary(input_format_t::msgpack, 1, result) && assign_and_return_true(subtype);
|
||||||
get_binary(input_format_t::msgpack, 1, result) &&
|
|
||||||
assign_and_return_true(subtype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD5: // fixext 2
|
case 0xD5: // fixext 2
|
||||||
{
|
{
|
||||||
std::int8_t subtype{};
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, subtype) &&
|
return get_number(input_format_t::msgpack, subtype) && get_binary(input_format_t::msgpack, 2, result) && assign_and_return_true(subtype);
|
||||||
get_binary(input_format_t::msgpack, 2, result) &&
|
|
||||||
assign_and_return_true(subtype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD6: // fixext 4
|
case 0xD6: // fixext 4
|
||||||
{
|
{
|
||||||
std::int8_t subtype{};
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, subtype) &&
|
return get_number(input_format_t::msgpack, subtype) && get_binary(input_format_t::msgpack, 4, result) && assign_and_return_true(subtype);
|
||||||
get_binary(input_format_t::msgpack, 4, result) &&
|
|
||||||
assign_and_return_true(subtype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD7: // fixext 8
|
case 0xD7: // fixext 8
|
||||||
{
|
{
|
||||||
std::int8_t subtype{};
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, subtype) &&
|
return get_number(input_format_t::msgpack, subtype) && get_binary(input_format_t::msgpack, 8, result) && assign_and_return_true(subtype);
|
||||||
get_binary(input_format_t::msgpack, 8, result) &&
|
|
||||||
assign_and_return_true(subtype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD8: // fixext 16
|
case 0xD8: // fixext 16
|
||||||
{
|
{
|
||||||
std::int8_t subtype{};
|
std::int8_t subtype{};
|
||||||
return get_number(input_format_t::msgpack, subtype) &&
|
return get_number(input_format_t::msgpack, subtype) && get_binary(input_format_t::msgpack, 16, result) && assign_and_return_true(subtype);
|
||||||
get_binary(input_format_t::msgpack, 16, result) &&
|
|
||||||
assign_and_return_true(subtype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default: // LCOV_EXCL_LINE
|
default: // LCOV_EXCL_LINE
|
||||||
@@ -2034,8 +2049,12 @@ class binary_reader
|
|||||||
}
|
}
|
||||||
if (number < 0)
|
if (number < 0)
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
|
return sax->parse_error(chars_read,
|
||||||
exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
|
get_token_string(),
|
||||||
|
parse_error::create(113,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format, "count in an optimized container must be positive", "size"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
|
result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
|
||||||
return true;
|
return true;
|
||||||
@@ -2050,8 +2069,12 @@ class binary_reader
|
|||||||
}
|
}
|
||||||
if (number < 0)
|
if (number < 0)
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
|
return sax->parse_error(chars_read,
|
||||||
exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
|
get_token_string(),
|
||||||
|
parse_error::create(113,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format, "count in an optimized container must be positive", "size"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
result = static_cast<std::size_t>(number);
|
result = static_cast<std::size_t>(number);
|
||||||
return true;
|
return true;
|
||||||
@@ -2066,8 +2089,12 @@ class binary_reader
|
|||||||
}
|
}
|
||||||
if (number < 0)
|
if (number < 0)
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
|
return sax->parse_error(chars_read,
|
||||||
exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
|
get_token_string(),
|
||||||
|
parse_error::create(113,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format, "count in an optimized container must be positive", "size"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
result = static_cast<std::size_t>(number);
|
result = static_cast<std::size_t>(number);
|
||||||
return true;
|
return true;
|
||||||
@@ -2082,13 +2109,18 @@ class binary_reader
|
|||||||
}
|
}
|
||||||
if (number < 0)
|
if (number < 0)
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
|
return sax->parse_error(chars_read,
|
||||||
exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
|
get_token_string(),
|
||||||
|
parse_error::create(113,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format, "count in an optimized container must be positive", "size"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
if (!value_in_range_of<std::size_t>(number))
|
if (!value_in_range_of<std::size_t>(number))
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
|
return sax->parse_error(chars_read,
|
||||||
exception_message(input_format, "integer value overflow", "size"), nullptr));
|
get_token_string(),
|
||||||
|
out_of_range::create(408, exception_message(input_format, "integer value overflow", "size"), nullptr));
|
||||||
}
|
}
|
||||||
result = static_cast<std::size_t>(number);
|
result = static_cast<std::size_t>(number);
|
||||||
return true;
|
return true;
|
||||||
@@ -2137,8 +2169,9 @@ class binary_reader
|
|||||||
}
|
}
|
||||||
if (!value_in_range_of<std::size_t>(number))
|
if (!value_in_range_of<std::size_t>(number))
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
|
return sax->parse_error(chars_read,
|
||||||
exception_message(input_format, "integer value overflow", "size"), nullptr));
|
get_token_string(),
|
||||||
|
out_of_range::create(408, exception_message(input_format, "integer value overflow", "size"), nullptr));
|
||||||
}
|
}
|
||||||
result = detail::conditional_static_cast<std::size_t>(number);
|
result = detail::conditional_static_cast<std::size_t>(number);
|
||||||
return true;
|
return true;
|
||||||
@@ -2152,7 +2185,10 @@ class binary_reader
|
|||||||
}
|
}
|
||||||
if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
|
if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimensional vector is not allowed", "size"), nullptr));
|
return sax->parse_error(
|
||||||
|
chars_read,
|
||||||
|
get_token_string(),
|
||||||
|
parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimensional vector is not allowed", "size"), nullptr));
|
||||||
}
|
}
|
||||||
std::vector<size_t> dim;
|
std::vector<size_t> dim;
|
||||||
if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
|
if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
|
||||||
@@ -2184,9 +2220,14 @@ class binary_reader
|
|||||||
for (auto i : dim)
|
for (auto i : dim)
|
||||||
{
|
{
|
||||||
result *= i;
|
result *= i;
|
||||||
if (result == 0 || result == npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be npos as it is used to initialize size in get_ubjson_size_type()
|
if (result == 0 ||
|
||||||
|
result ==
|
||||||
|
npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be npos as it is used to initialize size in get_ubjson_size_type()
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr));
|
return sax->parse_error(
|
||||||
|
chars_read,
|
||||||
|
get_token_string(),
|
||||||
|
out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr));
|
||||||
}
|
}
|
||||||
if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
|
if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
|
||||||
{
|
{
|
||||||
@@ -2239,12 +2280,17 @@ class binary_reader
|
|||||||
if (current == '$')
|
if (current == '$')
|
||||||
{
|
{
|
||||||
result.second = get(); // must not ignore 'N', because 'N' maybe the type
|
result.second = get(); // must not ignore 'N', because 'N' maybe the type
|
||||||
if (input_format == input_format_t::bjdata
|
if (input_format == input_format_t::bjdata &&
|
||||||
&& JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
|
JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(112,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
|
if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
|
||||||
@@ -2260,8 +2306,13 @@ class binary_reader
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(112,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
|
const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
|
||||||
@@ -2269,8 +2320,10 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
if (inside_ndarray)
|
if (inside_ndarray)
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
|
chars_read,
|
||||||
|
get_token_string(),
|
||||||
|
parse_error::create(112, chars_read, exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
|
||||||
}
|
}
|
||||||
result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
|
result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
|
||||||
}
|
}
|
||||||
@@ -2282,8 +2335,10 @@ class binary_reader
|
|||||||
const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
|
const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
|
||||||
if (input_format == input_format_t::bjdata && is_ndarray)
|
if (input_format == input_format_t::bjdata && is_ndarray)
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
|
chars_read,
|
||||||
|
get_token_string(),
|
||||||
|
parse_error::create(112, chars_read, exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
|
||||||
}
|
}
|
||||||
return is_error;
|
return is_error;
|
||||||
}
|
}
|
||||||
@@ -2399,8 +2454,7 @@ class binary_reader
|
|||||||
// half-precision floating-point numbers in the C language
|
// half-precision floating-point numbers in the C language
|
||||||
// is shown in Fig. 3.
|
// is shown in Fig. 3.
|
||||||
const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
|
const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
|
||||||
const double val = [&half]
|
const double val = [&half] {
|
||||||
{
|
|
||||||
const int exp = (half >> 10u) & 0x1Fu;
|
const int exp = (half >> 10u) & 0x1Fu;
|
||||||
const unsigned int mant = half & 0x3FFu;
|
const unsigned int mant = half & 0x3FFu;
|
||||||
JSON_ASSERT(0 <= exp && exp <= 32);
|
JSON_ASSERT(0 <= exp && exp <= 32);
|
||||||
@@ -2410,16 +2464,12 @@ class binary_reader
|
|||||||
case 0:
|
case 0:
|
||||||
return std::ldexp(mant, -24);
|
return std::ldexp(mant, -24);
|
||||||
case 31:
|
case 31:
|
||||||
return (mant == 0)
|
return (mant == 0) ? std::numeric_limits<double>::infinity() : std::numeric_limits<double>::quiet_NaN();
|
||||||
? std::numeric_limits<double>::infinity()
|
|
||||||
: std::numeric_limits<double>::quiet_NaN();
|
|
||||||
default:
|
default:
|
||||||
return std::ldexp(mant + 1024, exp - 25);
|
return std::ldexp(mant + 1024, exp - 25);
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
return sax->number_float((half & 0x8000u) != 0
|
return sax->number_float((half & 0x8000u) != 0 ? static_cast<number_float_t>(-val) : static_cast<number_float_t>(val), "");
|
||||||
? static_cast<number_float_t>(-val)
|
|
||||||
: static_cast<number_float_t>(val), "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
@@ -2449,8 +2499,14 @@ class binary_reader
|
|||||||
if (JSON_HEDLEY_UNLIKELY(current > 127))
|
if (JSON_HEDLEY_UNLIKELY(current > 127))
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(
|
||||||
|
113,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
string_t s(1, static_cast<typename string_t::value_type>(current));
|
string_t s(1, static_cast<typename string_t::value_type>(current));
|
||||||
return sax->string(s);
|
return sax->string(s);
|
||||||
@@ -2472,7 +2528,9 @@ class binary_reader
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));
|
return sax->parse_error(chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -2492,16 +2550,17 @@ class binary_reader
|
|||||||
if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
|
if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
|
||||||
{
|
{
|
||||||
size_and_type.second &= ~(static_cast<char_int_type>(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker
|
size_and_type.second &= ~(static_cast<char_int_type>(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker
|
||||||
auto it = std::lower_bound(bjd_types_map.begin(), bjd_types_map.end(), size_and_type.second, [](const bjd_type & p, char_int_type t)
|
auto it = std::lower_bound(bjd_types_map.begin(), bjd_types_map.end(), size_and_type.second, [](const bjd_type& p, char_int_type t) {
|
||||||
{
|
|
||||||
return p.first < t;
|
return p.first < t;
|
||||||
});
|
});
|
||||||
string_t key = "_ArrayType_";
|
string_t key = "_ArrayType_";
|
||||||
if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
|
if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t type = it->second; // sax->string() takes a reference
|
string_t type = it->second; // sax->string() takes a reference
|
||||||
@@ -2598,8 +2657,13 @@ class binary_reader
|
|||||||
if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
|
if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
|
||||||
{
|
{
|
||||||
auto last_token = get_token_string();
|
auto last_token = get_token_string();
|
||||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
|
chars_read,
|
||||||
|
last_token,
|
||||||
|
parse_error::create(112,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t key;
|
string_t key;
|
||||||
@@ -2703,8 +2767,13 @@ class binary_reader
|
|||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
|
if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
|
chars_read,
|
||||||
|
number_string,
|
||||||
|
parse_error::create(115,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (result_number)
|
switch (result_number)
|
||||||
@@ -2730,8 +2799,14 @@ class binary_reader
|
|||||||
case token_type::end_of_input:
|
case token_type::end_of_input:
|
||||||
case token_type::literal_or_value:
|
case token_type::literal_or_value:
|
||||||
default:
|
default:
|
||||||
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
|
return sax->parse_error(
|
||||||
exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
|
chars_read,
|
||||||
|
number_string,
|
||||||
|
parse_error::create(
|
||||||
|
115,
|
||||||
|
chars_read,
|
||||||
|
exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"),
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2762,8 +2837,7 @@ class binary_reader
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
get();
|
get();
|
||||||
}
|
} while (current == 'N');
|
||||||
while (current == 'N');
|
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
@@ -2827,9 +2901,7 @@ class binary_reader
|
|||||||
the input before we run out of string memory.
|
the input before we run out of string memory.
|
||||||
*/
|
*/
|
||||||
template<typename NumberType>
|
template<typename NumberType>
|
||||||
bool get_string(const input_format_t format,
|
bool get_string(const input_format_t format, const NumberType len, string_t& result)
|
||||||
const NumberType len,
|
|
||||||
string_t& result)
|
|
||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
for (NumberType i = 0; i < len; i++)
|
for (NumberType i = 0; i < len; i++)
|
||||||
@@ -2860,9 +2932,7 @@ class binary_reader
|
|||||||
the input before we run out of memory.
|
the input before we run out of memory.
|
||||||
*/
|
*/
|
||||||
template<typename NumberType>
|
template<typename NumberType>
|
||||||
bool get_binary(const input_format_t format,
|
bool get_binary(const input_format_t format, const NumberType len, binary_t& result)
|
||||||
const NumberType len,
|
|
||||||
binary_t& result)
|
|
||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
for (NumberType i = 0; i < len; i++)
|
for (NumberType i = 0; i < len; i++)
|
||||||
@@ -2888,7 +2958,8 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(current == char_traits<char_type>::eof()))
|
if (JSON_HEDLEY_UNLIKELY(current == char_traits<char_type>::eof()))
|
||||||
{
|
{
|
||||||
return sax->parse_error(chars_read, "<end of file>",
|
return sax->parse_error(chars_read,
|
||||||
|
"<end of file>",
|
||||||
parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
|
parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -2900,7 +2971,8 @@ class binary_reader
|
|||||||
std::string get_token_string() const
|
std::string get_token_string() const
|
||||||
{
|
{
|
||||||
std::array<char, 3> cr{ {} };
|
std::array<char, 3> cr{ {} };
|
||||||
static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
static_cast<void>(
|
||||||
|
(std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
return std::string{ cr.data() };
|
return std::string{ cr.data() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2910,9 +2982,7 @@ class binary_reader
|
|||||||
@param[in] context further context information
|
@param[in] context further context information
|
||||||
@return a message string to use in the parse_error exceptions
|
@return a message string to use in the parse_error exceptions
|
||||||
*/
|
*/
|
||||||
std::string exception_message(const input_format_t format,
|
std::string exception_message(const input_format_t format, const std::string& detail, const std::string& context) const
|
||||||
const std::string& detail,
|
|
||||||
const std::string& context) const
|
|
||||||
{
|
{
|
||||||
std::string error_msg = "syntax error while parsing ";
|
std::string error_msg = "syntax error while parsing ";
|
||||||
|
|
||||||
@@ -2968,12 +3038,10 @@ class binary_reader
|
|||||||
json_sax_t* sax = nullptr;
|
json_sax_t* sax = nullptr;
|
||||||
|
|
||||||
// excluded markers in bjdata optimized type
|
// excluded markers in bjdata optimized type
|
||||||
#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \
|
#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
|
||||||
make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
|
|
||||||
|
|
||||||
#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
|
#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
|
||||||
make_array<bjd_type>( \
|
make_array<bjd_type>(bjd_type{ 'C', "char" }, \
|
||||||
bjd_type{'C', "char"}, \
|
|
||||||
bjd_type{ 'D', "double" }, \
|
bjd_type{ 'D', "double" }, \
|
||||||
bjd_type{ 'I', "int16" }, \
|
bjd_type{ 'I', "int16" }, \
|
||||||
bjd_type{ 'L', "int64" }, \
|
bjd_type{ 'L', "int64" }, \
|
||||||
@@ -2988,13 +3056,11 @@ class binary_reader
|
|||||||
JSON_PRIVATE_UNLESS_TESTED :
|
JSON_PRIVATE_UNLESS_TESTED :
|
||||||
// lookup tables
|
// lookup tables
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
|
// NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
|
||||||
const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =
|
const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers = JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_;
|
||||||
JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_;
|
|
||||||
|
|
||||||
using bjd_type = std::pair<char_int_type, string_t>;
|
using bjd_type = std::pair<char_int_type, string_t>;
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
|
// NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
|
||||||
const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map =
|
const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map = JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_;
|
||||||
JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_;
|
|
||||||
|
|
||||||
#undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
|
#undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
|
||||||
#undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
|
#undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
|
||||||
|
|||||||
@@ -32,7 +32,15 @@ namespace detail
|
|||||||
{
|
{
|
||||||
|
|
||||||
/// the supported input formats
|
/// the supported input formats
|
||||||
enum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata };
|
enum class input_format_t
|
||||||
|
{
|
||||||
|
json,
|
||||||
|
cbor,
|
||||||
|
msgpack,
|
||||||
|
ubjson,
|
||||||
|
bson,
|
||||||
|
bjdata
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////
|
////////////////////
|
||||||
// input adapters //
|
// input adapters //
|
||||||
@@ -97,7 +105,8 @@ class input_stream_adapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
explicit input_stream_adapter(std::istream& i)
|
explicit input_stream_adapter(std::istream& i)
|
||||||
: is(&i), sb(i.rdbuf())
|
: is(&i)
|
||||||
|
, sb(i.rdbuf())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// delete because of pointer members
|
// delete because of pointer members
|
||||||
@@ -106,7 +115,8 @@ class input_stream_adapter
|
|||||||
input_stream_adapter& operator=(input_stream_adapter&&) = delete;
|
input_stream_adapter& operator=(input_stream_adapter&&) = delete;
|
||||||
|
|
||||||
input_stream_adapter(input_stream_adapter&& rhs) noexcept
|
input_stream_adapter(input_stream_adapter&& rhs) noexcept
|
||||||
: is(rhs.is), sb(rhs.sb)
|
: is(rhs.is)
|
||||||
|
, sb(rhs.sb)
|
||||||
{
|
{
|
||||||
rhs.is = nullptr;
|
rhs.is = nullptr;
|
||||||
rhs.sb = nullptr;
|
rhs.sb = nullptr;
|
||||||
@@ -142,7 +152,8 @@ class iterator_input_adapter
|
|||||||
using char_type = typename std::iterator_traits<IteratorType>::value_type;
|
using char_type = typename std::iterator_traits<IteratorType>::value_type;
|
||||||
|
|
||||||
iterator_input_adapter(IteratorType first, IteratorType last)
|
iterator_input_adapter(IteratorType first, IteratorType last)
|
||||||
: current(std::move(first)), end(std::move(last))
|
: current(std::move(first))
|
||||||
|
, end(std::move(last))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
typename char_traits<char_type>::int_type get_character()
|
typename char_traits<char_type>::int_type get_character()
|
||||||
@@ -177,10 +188,8 @@ template<typename BaseInputAdapter>
|
|||||||
struct wide_string_input_helper<BaseInputAdapter, 4>
|
struct wide_string_input_helper<BaseInputAdapter, 4>
|
||||||
{
|
{
|
||||||
// UTF-32
|
// UTF-32
|
||||||
static void fill_buffer(BaseInputAdapter& input,
|
static void
|
||||||
std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
|
fill_buffer(BaseInputAdapter& input, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, size_t& utf8_bytes_index, size_t& utf8_bytes_filled)
|
||||||
size_t& utf8_bytes_index,
|
|
||||||
size_t& utf8_bytes_filled)
|
|
||||||
{
|
{
|
||||||
utf8_bytes_index = 0;
|
utf8_bytes_index = 0;
|
||||||
|
|
||||||
@@ -235,10 +244,8 @@ template<typename BaseInputAdapter>
|
|||||||
struct wide_string_input_helper<BaseInputAdapter, 2>
|
struct wide_string_input_helper<BaseInputAdapter, 2>
|
||||||
{
|
{
|
||||||
// UTF-16
|
// UTF-16
|
||||||
static void fill_buffer(BaseInputAdapter& input,
|
static void
|
||||||
std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
|
fill_buffer(BaseInputAdapter& input, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, size_t& utf8_bytes_index, size_t& utf8_bytes_filled)
|
||||||
size_t& utf8_bytes_index,
|
|
||||||
size_t& utf8_bytes_filled)
|
|
||||||
{
|
{
|
||||||
utf8_bytes_index = 0;
|
utf8_bytes_index = 0;
|
||||||
|
|
||||||
@@ -301,7 +308,8 @@ class wide_string_input_adapter
|
|||||||
using char_type = char;
|
using char_type = char;
|
||||||
|
|
||||||
wide_string_input_adapter(BaseInputAdapter base)
|
wide_string_input_adapter(BaseInputAdapter base)
|
||||||
: base_adapter(base) {}
|
: base_adapter(base)
|
||||||
|
{}
|
||||||
|
|
||||||
typename std::char_traits<char>::int_type get_character() noexcept
|
typename std::char_traits<char>::int_type get_character() noexcept
|
||||||
{
|
{
|
||||||
@@ -394,11 +402,11 @@ using std::begin;
|
|||||||
using std::end;
|
using std::end;
|
||||||
|
|
||||||
template<typename ContainerType, typename Enable = void>
|
template<typename ContainerType, typename Enable = void>
|
||||||
struct container_input_adapter_factory {};
|
struct container_input_adapter_factory
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
struct container_input_adapter_factory< ContainerType,
|
struct container_input_adapter_factory<ContainerType, void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
|
||||||
void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
|
|
||||||
{
|
{
|
||||||
using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
|
using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
|
||||||
|
|
||||||
@@ -437,12 +445,10 @@ inline input_stream_adapter input_adapter(std::istream&& stream)
|
|||||||
using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
|
using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
|
||||||
|
|
||||||
// Null-delimited strings, and the like.
|
// Null-delimited strings, and the like.
|
||||||
template < typename CharT,
|
template<
|
||||||
typename std::enable_if <
|
typename CharT,
|
||||||
std::is_pointer<CharT>::value&&
|
typename std::enable_if<std::is_pointer<CharT>::value && !std::is_array<CharT>::value &&
|
||||||
!std::is_array<CharT>::value&&
|
std::is_integral<typename std::remove_pointer<CharT>::type>::value && sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
||||||
std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
|
|
||||||
sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
contiguous_bytes_input_adapter input_adapter(CharT b)
|
contiguous_bytes_input_adapter input_adapter(CharT b)
|
||||||
{
|
{
|
||||||
@@ -452,7 +458,8 @@ contiguous_bytes_input_adapter input_adapter(CharT b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
auto input_adapter(T (&array)[N])
|
||||||
|
-> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||||
{
|
{
|
||||||
return input_adapter(array, array + N);
|
return input_adapter(array, array + N);
|
||||||
}
|
}
|
||||||
@@ -464,20 +471,19 @@ class span_input_adapter
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<typename CharT,
|
template<typename CharT,
|
||||||
typename std::enable_if <
|
typename std::enable_if<std::is_pointer<CharT>::value && std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
|
||||||
std::is_pointer<CharT>::value&&
|
|
||||||
std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
|
|
||||||
sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
sizeof(typename std::remove_pointer<CharT>::type) == 1,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
span_input_adapter(CharT b, std::size_t l)
|
span_input_adapter(CharT b, std::size_t l)
|
||||||
: ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
|
: ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l)
|
||||||
|
{}
|
||||||
|
|
||||||
template<class IteratorType,
|
template<
|
||||||
typename std::enable_if<
|
class IteratorType,
|
||||||
std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
|
typename std::enable_if<std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value, int>::type = 0>
|
||||||
int>::type = 0>
|
|
||||||
span_input_adapter(IteratorType first, IteratorType last)
|
span_input_adapter(IteratorType first, IteratorType last)
|
||||||
: ia(input_adapter(first, last)) {}
|
: ia(input_adapter(first, last))
|
||||||
|
{}
|
||||||
|
|
||||||
contiguous_bytes_input_adapter&& get()
|
contiguous_bytes_input_adapter&& get()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -130,9 +130,7 @@ struct json_sax
|
|||||||
@param[in] ex an exception object describing the error
|
@param[in] ex an exception object describing the error
|
||||||
@return whether parsing should proceed (must return false)
|
@return whether parsing should proceed (must return false)
|
||||||
*/
|
*/
|
||||||
virtual bool parse_error(std::size_t position,
|
virtual bool parse_error(std::size_t position, const std::string& last_token, const detail::exception& ex) = 0;
|
||||||
const std::string& last_token,
|
|
||||||
const detail::exception& ex) = 0;
|
|
||||||
|
|
||||||
json_sax() = default;
|
json_sax() = default;
|
||||||
json_sax(const json_sax&) = default;
|
json_sax(const json_sax&) = default;
|
||||||
@@ -173,7 +171,8 @@ class json_sax_dom_parser
|
|||||||
@param[in] allow_exceptions_ whether parse errors yield exceptions
|
@param[in] allow_exceptions_ whether parse errors yield exceptions
|
||||||
*/
|
*/
|
||||||
explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
|
explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
|
||||||
: root(r), allow_exceptions(allow_exceptions_)
|
: root(r)
|
||||||
|
, allow_exceptions(allow_exceptions_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// make class move-only
|
// make class move-only
|
||||||
@@ -280,8 +279,7 @@ class json_sax_dom_parser
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Exception>
|
template<class Exception>
|
||||||
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
|
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const Exception& ex)
|
||||||
const Exception& ex)
|
|
||||||
{
|
{
|
||||||
errored = true;
|
errored = true;
|
||||||
static_cast<void>(ex);
|
static_cast<void>(ex);
|
||||||
@@ -305,8 +303,7 @@ class json_sax_dom_parser
|
|||||||
object to which we can add elements
|
object to which we can add elements
|
||||||
*/
|
*/
|
||||||
template<typename Value>
|
template<typename Value>
|
||||||
JSON_HEDLEY_RETURNS_NON_NULL
|
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType* handle_value(Value&& v)
|
||||||
BasicJsonType* handle_value(Value&& v)
|
|
||||||
{
|
{
|
||||||
if (ref_stack.empty())
|
if (ref_stack.empty())
|
||||||
{
|
{
|
||||||
@@ -352,10 +349,10 @@ class json_sax_dom_callback_parser
|
|||||||
using parser_callback_t = typename BasicJsonType::parser_callback_t;
|
using parser_callback_t = typename BasicJsonType::parser_callback_t;
|
||||||
using parse_event_t = typename BasicJsonType::parse_event_t;
|
using parse_event_t = typename BasicJsonType::parse_event_t;
|
||||||
|
|
||||||
json_sax_dom_callback_parser(BasicJsonType& r,
|
json_sax_dom_callback_parser(BasicJsonType& r, const parser_callback_t cb, const bool allow_exceptions_ = true)
|
||||||
const parser_callback_t cb,
|
: root(r)
|
||||||
const bool allow_exceptions_ = true)
|
, callback(cb)
|
||||||
: root(r), callback(cb), allow_exceptions(allow_exceptions_)
|
, allow_exceptions(allow_exceptions_)
|
||||||
{
|
{
|
||||||
keep_stack.push_back(true);
|
keep_stack.push_back(true);
|
||||||
}
|
}
|
||||||
@@ -530,8 +527,7 @@ class json_sax_dom_callback_parser
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Exception>
|
template<class Exception>
|
||||||
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
|
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const Exception& ex)
|
||||||
const Exception& ex)
|
|
||||||
{
|
{
|
||||||
errored = true;
|
errored = true;
|
||||||
static_cast<void>(ex);
|
static_cast<void>(ex);
|
||||||
|
|||||||
@@ -1185,8 +1185,7 @@ scan_number_exponent:
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
error_message =
|
error_message = "invalid number; expected '+', '-', or digit after exponent";
|
||||||
"invalid number; expected '+', '-', or digit after exponent";
|
|
||||||
return token_type::parse_error;
|
return token_type::parse_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1298,8 +1297,7 @@ scan_number_done:
|
|||||||
@param[in] return_type the token type to return on success
|
@param[in] return_type the token type to return on success
|
||||||
*/
|
*/
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
token_type scan_literal(const char_type* literal_text, const std::size_t length,
|
token_type scan_literal(const char_type* literal_text, const std::size_t length, token_type return_type)
|
||||||
token_type return_type)
|
|
||||||
{
|
{
|
||||||
JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);
|
JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);
|
||||||
for (std::size_t i = 1; i < length; ++i)
|
for (std::size_t i = 1; i < length; ++i)
|
||||||
@@ -1456,7 +1454,8 @@ scan_number_done:
|
|||||||
{
|
{
|
||||||
// escape control characters
|
// escape control characters
|
||||||
std::array<char, 9> cs{ {} };
|
std::array<char, 9> cs{ {} };
|
||||||
static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
static_cast<void>(( // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
|
std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)));
|
||||||
result += cs.data();
|
result += cs.data();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1503,8 +1502,7 @@ scan_number_done:
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
get();
|
get();
|
||||||
}
|
} while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
|
||||||
while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
token_type scan()
|
token_type scan()
|
||||||
@@ -1550,17 +1548,25 @@ scan_number_done:
|
|||||||
// literals
|
// literals
|
||||||
case 't':
|
case 't':
|
||||||
{
|
{
|
||||||
std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
|
std::array<char_type, 4> true_literal = {
|
||||||
|
{ static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e') }
|
||||||
|
};
|
||||||
return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
|
return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
|
||||||
}
|
}
|
||||||
case 'f':
|
case 'f':
|
||||||
{
|
{
|
||||||
std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
|
std::array<char_type, 5> false_literal = { { static_cast<char_type>('f'),
|
||||||
|
static_cast<char_type>('a'),
|
||||||
|
static_cast<char_type>('l'),
|
||||||
|
static_cast<char_type>('s'),
|
||||||
|
static_cast<char_type>('e') } };
|
||||||
return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
|
return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
|
||||||
}
|
}
|
||||||
case 'n':
|
case 'n':
|
||||||
{
|
{
|
||||||
std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
|
std::array<char_type, 4> null_literal = {
|
||||||
|
{ static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l') }
|
||||||
|
};
|
||||||
return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
|
return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ enum class parse_event_t : std::uint8_t
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
using parser_callback_t =
|
using parser_callback_t = std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
|
||||||
std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief syntax analysis
|
@brief syntax analysis
|
||||||
@@ -102,8 +101,7 @@ class parser
|
|||||||
{
|
{
|
||||||
sdp.parse_error(m_lexer.get_position(),
|
sdp.parse_error(m_lexer.get_position(),
|
||||||
m_lexer.get_token_string(),
|
m_lexer.get_token_string(),
|
||||||
parse_error::create(101, m_lexer.get_position(),
|
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
|
||||||
exception_message(token_type::end_of_input, "value"), nullptr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// in case of an error, return discarded value
|
// in case of an error, return discarded value
|
||||||
@@ -212,7 +210,8 @@ class parser
|
|||||||
// parse key
|
// parse key
|
||||||
if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
|
if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
|
||||||
{
|
{
|
||||||
return sax->parse_error(m_lexer.get_position(),
|
return sax->parse_error(
|
||||||
|
m_lexer.get_position(),
|
||||||
m_lexer.get_token_string(),
|
m_lexer.get_token_string(),
|
||||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
|
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
|
||||||
}
|
}
|
||||||
@@ -224,7 +223,8 @@ class parser
|
|||||||
// parse separator (:)
|
// parse separator (:)
|
||||||
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
|
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
|
||||||
{
|
{
|
||||||
return sax->parse_error(m_lexer.get_position(),
|
return sax->parse_error(
|
||||||
|
m_lexer.get_position(),
|
||||||
m_lexer.get_token_string(),
|
m_lexer.get_token_string(),
|
||||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
|
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
|
||||||
}
|
}
|
||||||
@@ -337,7 +337,8 @@ class parser
|
|||||||
case token_type::parse_error:
|
case token_type::parse_error:
|
||||||
{
|
{
|
||||||
// using "uninitialized" to avoid "expected" message
|
// using "uninitialized" to avoid "expected" message
|
||||||
return sax->parse_error(m_lexer.get_position(),
|
return sax->parse_error(
|
||||||
|
m_lexer.get_position(),
|
||||||
m_lexer.get_token_string(),
|
m_lexer.get_token_string(),
|
||||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
|
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
|
||||||
}
|
}
|
||||||
@@ -345,13 +346,17 @@ class parser
|
|||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1))
|
if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1))
|
||||||
{
|
{
|
||||||
return sax->parse_error(m_lexer.get_position(),
|
return sax->parse_error(
|
||||||
|
m_lexer.get_position(),
|
||||||
m_lexer.get_token_string(),
|
m_lexer.get_token_string(),
|
||||||
parse_error::create(101, m_lexer.get_position(),
|
parse_error::create(101,
|
||||||
"attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
|
m_lexer.get_position(),
|
||||||
|
"attempting to parse an empty input; check that your input string or stream contains the expected JSON",
|
||||||
|
nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sax->parse_error(m_lexer.get_position(),
|
return sax->parse_error(
|
||||||
|
m_lexer.get_position(),
|
||||||
m_lexer.get_token_string(),
|
m_lexer.get_token_string(),
|
||||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
|
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
|
||||||
}
|
}
|
||||||
@@ -363,7 +368,8 @@ class parser
|
|||||||
case token_type::literal_or_value:
|
case token_type::literal_or_value:
|
||||||
default: // the last token was unexpected
|
default: // the last token was unexpected
|
||||||
{
|
{
|
||||||
return sax->parse_error(m_lexer.get_position(),
|
return sax->parse_error(
|
||||||
|
m_lexer.get_position(),
|
||||||
m_lexer.get_token_string(),
|
m_lexer.get_token_string(),
|
||||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
|
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
|
||||||
}
|
}
|
||||||
@@ -422,7 +428,8 @@ class parser
|
|||||||
// parse key
|
// parse key
|
||||||
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
|
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
|
||||||
{
|
{
|
||||||
return sax->parse_error(m_lexer.get_position(),
|
return sax->parse_error(
|
||||||
|
m_lexer.get_position(),
|
||||||
m_lexer.get_token_string(),
|
m_lexer.get_token_string(),
|
||||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
|
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
|
||||||
}
|
}
|
||||||
@@ -435,7 +442,8 @@ class parser
|
|||||||
// parse separator (:)
|
// parse separator (:)
|
||||||
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
|
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
|
||||||
{
|
{
|
||||||
return sax->parse_error(m_lexer.get_position(),
|
return sax->parse_error(
|
||||||
|
m_lexer.get_position(),
|
||||||
m_lexer.get_token_string(),
|
m_lexer.get_token_string(),
|
||||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
|
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
|
||||||
}
|
}
|
||||||
@@ -488,8 +496,7 @@ class parser
|
|||||||
|
|
||||||
if (last_token == token_type::parse_error)
|
if (last_token == token_type::parse_error)
|
||||||
{
|
{
|
||||||
error_msg += concat(m_lexer.get_error_message(), "; last read: '",
|
error_msg += concat(m_lexer.get_error_message(), "; last read: '", m_lexer.get_token_string(), '\'');
|
||||||
m_lexer.get_token_string(), '\'');
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ namespace detail
|
|||||||
@note This structure could easily be a union, but MSVC currently does not allow
|
@note This structure could easily be a union, but MSVC currently does not allow
|
||||||
unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
|
unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
|
||||||
*/
|
*/
|
||||||
template<typename BasicJsonType> struct internal_iterator
|
template<typename BasicJsonType>
|
||||||
|
struct internal_iterator
|
||||||
{
|
{
|
||||||
/// iterator for JSON objects
|
/// iterator for JSON objects
|
||||||
typename BasicJsonType::object_t::iterator object_iterator{};
|
typename BasicJsonType::object_t::iterator object_iterator{};
|
||||||
|
|||||||
@@ -24,8 +24,10 @@ namespace detail
|
|||||||
{
|
{
|
||||||
|
|
||||||
// forward declare, to be able to friend it later on
|
// forward declare, to be able to friend it later on
|
||||||
template<typename IteratorType> class iteration_proxy;
|
template<typename IteratorType>
|
||||||
template<typename IteratorType> class iteration_proxy_value;
|
class iteration_proxy;
|
||||||
|
template<typename IteratorType>
|
||||||
|
class iteration_proxy_value;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief a template for a bidirectional iterator for the @ref basic_json class
|
@brief a template for a bidirectional iterator for the @ref basic_json class
|
||||||
@@ -47,7 +49,8 @@ template<typename BasicJsonType>
|
|||||||
class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
|
class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
|
||||||
{
|
{
|
||||||
/// the iterator with BasicJsonType of different const-ness
|
/// the iterator with BasicJsonType of different const-ness
|
||||||
using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
|
using other_iter_impl =
|
||||||
|
iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
|
||||||
/// allow basic_json to access private members
|
/// allow basic_json to access private members
|
||||||
friend other_iter_impl;
|
friend other_iter_impl;
|
||||||
friend BasicJsonType;
|
friend BasicJsonType;
|
||||||
@@ -57,11 +60,10 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
using object_t = typename BasicJsonType::object_t;
|
using object_t = typename BasicJsonType::object_t;
|
||||||
using array_t = typename BasicJsonType::array_t;
|
using array_t = typename BasicJsonType::array_t;
|
||||||
// make sure BasicJsonType is basic_json or const basic_json
|
// make sure BasicJsonType is basic_json or const basic_json
|
||||||
static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
|
static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value, "iter_impl only accepts (const) basic_json");
|
||||||
"iter_impl only accepts (const) basic_json");
|
|
||||||
// superficial check for the LegacyBidirectionalIterator named requirement
|
// superficial check for the LegacyBidirectionalIterator named requirement
|
||||||
static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
|
static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value &&
|
||||||
&& std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
|
std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
|
||||||
"basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
|
"basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -77,14 +79,11 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
/// a type to represent differences between iterators
|
/// a type to represent differences between iterators
|
||||||
using difference_type = typename BasicJsonType::difference_type;
|
using difference_type = typename BasicJsonType::difference_type;
|
||||||
/// defines a pointer to the type iterated over (value_type)
|
/// defines a pointer to the type iterated over (value_type)
|
||||||
using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
|
using pointer =
|
||||||
typename BasicJsonType::const_pointer,
|
typename std::conditional<std::is_const<BasicJsonType>::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer>::type;
|
||||||
typename BasicJsonType::pointer>::type;
|
|
||||||
/// defines a reference to the type iterated over (value_type)
|
/// defines a reference to the type iterated over (value_type)
|
||||||
using reference =
|
using reference =
|
||||||
typename std::conditional<std::is_const<BasicJsonType>::value,
|
typename std::conditional<std::is_const<BasicJsonType>::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference>::type;
|
||||||
typename BasicJsonType::const_reference,
|
|
||||||
typename BasicJsonType::reference>::type;
|
|
||||||
|
|
||||||
iter_impl() = default;
|
iter_impl() = default;
|
||||||
~iter_impl() = default;
|
~iter_impl() = default;
|
||||||
@@ -97,7 +96,8 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
@pre object != nullptr
|
@pre object != nullptr
|
||||||
@post The iterator is initialized; i.e. `m_object != nullptr`.
|
@post The iterator is initialized; i.e. `m_object != nullptr`.
|
||||||
*/
|
*/
|
||||||
explicit iter_impl(pointer object) noexcept : m_object(object)
|
explicit iter_impl(pointer object) noexcept
|
||||||
|
: m_object(object)
|
||||||
{
|
{
|
||||||
JSON_ASSERT(m_object != nullptr);
|
JSON_ASSERT(m_object != nullptr);
|
||||||
|
|
||||||
@@ -148,7 +148,8 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
information refer to: https://github.com/nlohmann/json/issues/1608
|
information refer to: https://github.com/nlohmann/json/issues/1608
|
||||||
*/
|
*/
|
||||||
iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
|
iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
|
||||||
: m_object(other.m_object), m_it(other.m_it)
|
: m_object(other.m_object)
|
||||||
|
, m_it(other.m_it)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -173,7 +174,8 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
@note It is not checked whether @a other is initialized.
|
@note It is not checked whether @a other is initialized.
|
||||||
*/
|
*/
|
||||||
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
|
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
|
||||||
: m_object(other.m_object), m_it(other.m_it)
|
: m_object(other.m_object)
|
||||||
|
, m_it(other.m_it)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -465,7 +467,8 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
@brief comparison: equal
|
@brief comparison: equal
|
||||||
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
||||||
*/
|
*/
|
||||||
template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
|
template<typename IterImpl,
|
||||||
|
detail::enable_if_t<(std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t> = nullptr>
|
||||||
bool operator==(const IterImpl& other) const
|
bool operator==(const IterImpl& other) const
|
||||||
{
|
{
|
||||||
// if objects are not the same, the comparison is undefined
|
// if objects are not the same, the comparison is undefined
|
||||||
@@ -501,7 +504,8 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
@brief comparison: not equal
|
@brief comparison: not equal
|
||||||
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
@pre The iterator is initialized; i.e. `m_object != nullptr`.
|
||||||
*/
|
*/
|
||||||
template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
|
template<typename IterImpl,
|
||||||
|
detail::enable_if_t<(std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t> = nullptr>
|
||||||
bool operator!=(const IterImpl& other) const
|
bool operator!=(const IterImpl& other) const
|
||||||
{
|
{
|
||||||
return !operator==(other);
|
return !operator==(other);
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ void int_to_string( string_type& target, std::size_t value )
|
|||||||
using std::to_string;
|
using std::to_string;
|
||||||
target = to_string(value);
|
target = to_string(value);
|
||||||
}
|
}
|
||||||
template<typename IteratorType> class iteration_proxy_value
|
template<typename IteratorType>
|
||||||
|
class iteration_proxy_value
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
@@ -57,9 +58,8 @@ template<typename IteratorType> class iteration_proxy_value
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit iteration_proxy_value() = default;
|
explicit iteration_proxy_value() = default;
|
||||||
explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
|
explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0) noexcept(std::is_nothrow_move_constructible<IteratorType>::value &&
|
||||||
noexcept(std::is_nothrow_move_constructible<IteratorType>::value
|
std::is_nothrow_default_constructible<string_type>::value)
|
||||||
&& std::is_nothrow_default_constructible<string_type>::value)
|
|
||||||
: anchor(std::move(it))
|
: anchor(std::move(it))
|
||||||
, array_index(array_index_)
|
, array_index(array_index_)
|
||||||
{}
|
{}
|
||||||
@@ -67,12 +67,12 @@ template<typename IteratorType> class iteration_proxy_value
|
|||||||
iteration_proxy_value(iteration_proxy_value const&) = default;
|
iteration_proxy_value(iteration_proxy_value const&) = default;
|
||||||
iteration_proxy_value& operator=(iteration_proxy_value const&) = default;
|
iteration_proxy_value& operator=(iteration_proxy_value const&) = default;
|
||||||
// older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
|
// older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
|
||||||
iteration_proxy_value(iteration_proxy_value&&)
|
iteration_proxy_value(iteration_proxy_value&&) noexcept(std::is_nothrow_move_constructible<IteratorType>::value &&
|
||||||
noexcept(std::is_nothrow_move_constructible<IteratorType>::value
|
std::is_nothrow_move_constructible<string_type>::value) =
|
||||||
&& std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
|
default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
|
||||||
iteration_proxy_value& operator=(iteration_proxy_value&&)
|
iteration_proxy_value& operator=(iteration_proxy_value&&) noexcept(std::is_nothrow_move_assignable<IteratorType>::value &&
|
||||||
noexcept(std::is_nothrow_move_assignable<IteratorType>::value
|
std::is_nothrow_move_assignable<string_type>::value) =
|
||||||
&& std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
|
default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
|
||||||
~iteration_proxy_value() = default;
|
~iteration_proxy_value() = default;
|
||||||
|
|
||||||
/// dereference operator (needed for range-based for)
|
/// dereference operator (needed for range-based for)
|
||||||
@@ -154,7 +154,8 @@ template<typename IteratorType> class iteration_proxy_value
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// proxy class for the items() function
|
/// proxy class for the items() function
|
||||||
template<typename IteratorType> class iteration_proxy
|
template<typename IteratorType>
|
||||||
|
class iteration_proxy
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/// the container to iterate
|
/// the container to iterate
|
||||||
@@ -165,7 +166,8 @@ template<typename IteratorType> class iteration_proxy
|
|||||||
|
|
||||||
/// construct iteration proxy from a container
|
/// construct iteration proxy from a container
|
||||||
explicit iteration_proxy(typename IteratorType::reference cont) noexcept
|
explicit iteration_proxy(typename IteratorType::reference cont) noexcept
|
||||||
: container(&cont) {}
|
: container(&cont)
|
||||||
|
{}
|
||||||
|
|
||||||
iteration_proxy(iteration_proxy const&) = default;
|
iteration_proxy(iteration_proxy const&) = default;
|
||||||
iteration_proxy& operator=(iteration_proxy const&) = default;
|
iteration_proxy& operator=(iteration_proxy const&) = default;
|
||||||
@@ -220,15 +222,14 @@ namespace std
|
|||||||
#endif
|
#endif
|
||||||
template<typename IteratorType>
|
template<typename IteratorType>
|
||||||
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
|
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
|
||||||
: public std::integral_constant<std::size_t, 2> {};
|
: public std::integral_constant<std::size_t, 2>
|
||||||
|
{};
|
||||||
|
|
||||||
template<std::size_t N, typename IteratorType>
|
template<std::size_t N, typename IteratorType>
|
||||||
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
|
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using type = decltype(
|
using type = decltype(get<N>(std::declval<::nlohmann::detail::iteration_proxy_value<IteratorType>>()));
|
||||||
get<N>(std::declval <
|
|
||||||
::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
|
|
||||||
};
|
};
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
|
|||||||
@@ -11,21 +11,21 @@
|
|||||||
#include <iterator> // random_access_iterator_tag
|
#include <iterator> // random_access_iterator_tag
|
||||||
|
|
||||||
#include <nlohmann/detail/abi_macros.hpp>
|
#include <nlohmann/detail/abi_macros.hpp>
|
||||||
#include <nlohmann/detail/meta/void_t.hpp>
|
|
||||||
#include <nlohmann/detail/meta/cpp_future.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
|
#include <nlohmann/detail/meta/void_t.hpp>
|
||||||
|
|
||||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename It, typename = void>
|
template<typename It, typename = void>
|
||||||
struct iterator_types {};
|
struct iterator_types
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename It>
|
template<typename It>
|
||||||
struct iterator_types<
|
struct iterator_types<
|
||||||
It,
|
It,
|
||||||
void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
|
void_t<typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category>>
|
||||||
typename It::reference, typename It::iterator_category >>
|
|
||||||
{
|
{
|
||||||
using difference_type = typename It::difference_type;
|
using difference_type = typename It::difference_type;
|
||||||
using value_type = typename It::value_type;
|
using value_type = typename It::value_type;
|
||||||
@@ -38,14 +38,11 @@ struct iterator_types <
|
|||||||
// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
|
// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
|
||||||
template<typename T, typename = void>
|
template<typename T, typename = void>
|
||||||
struct iterator_traits
|
struct iterator_traits
|
||||||
{
|
{};
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
|
struct iterator_traits<T, enable_if_t<!std::is_pointer<T>::value>> : iterator_types<T>
|
||||||
: iterator_types<T>
|
{};
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
|
struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
|
||||||
|
|||||||
@@ -52,10 +52,13 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
|
|||||||
|
|
||||||
/// create reverse iterator from iterator
|
/// create reverse iterator from iterator
|
||||||
explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
|
explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
|
||||||
: base_iterator(it) {}
|
: base_iterator(it)
|
||||||
|
{}
|
||||||
|
|
||||||
/// create reverse iterator from base class
|
/// create reverse iterator from base class
|
||||||
explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
|
explicit json_reverse_iterator(const base_iterator& it) noexcept
|
||||||
|
: base_iterator(it)
|
||||||
|
{}
|
||||||
|
|
||||||
/// post-increment (it++)
|
/// post-increment (it++)
|
||||||
json_reverse_iterator operator++(int) & // NOLINT(cert-dcl21-cpp)
|
json_reverse_iterator operator++(int) & // NOLINT(cert-dcl21-cpp)
|
||||||
|
|||||||
@@ -26,14 +26,11 @@ of @ref basic_json do not require complex case distinctions
|
|||||||
By default, this class is used because it is empty and thus has no effect
|
By default, this class is used because it is empty and thus has no effect
|
||||||
on the behavior of @ref basic_json.
|
on the behavior of @ref basic_json.
|
||||||
*/
|
*/
|
||||||
struct json_default_base {};
|
struct json_default_base
|
||||||
|
{};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
using json_base_class = typename std::conditional <
|
using json_base_class = typename std::conditional<std::is_same<T, void>::value, json_default_base, T>::type;
|
||||||
std::is_same<T, void>::value,
|
|
||||||
json_default_base,
|
|
||||||
T
|
|
||||||
>::type;
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|||||||
@@ -67,10 +67,7 @@ class json_pointer
|
|||||||
/// @sa https://json.nlohmann.me/api/json_pointer/to_string/
|
/// @sa https://json.nlohmann.me/api/json_pointer/to_string/
|
||||||
string_t to_string() const
|
string_t to_string() const
|
||||||
{
|
{
|
||||||
return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
|
return std::accumulate(reference_tokens.begin(), reference_tokens.end(), string_t{}, [](const string_t& a, const string_t& b) {
|
||||||
string_t{},
|
|
||||||
[](const string_t& a, const string_t& b)
|
|
||||||
{
|
|
||||||
return detail::concat(a, '/', detail::escape(b));
|
return detail::concat(a, '/', detail::escape(b));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -97,9 +94,7 @@ class json_pointer
|
|||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
|
||||||
json_pointer& operator/=(const json_pointer& ptr)
|
json_pointer& operator/=(const json_pointer& ptr)
|
||||||
{
|
{
|
||||||
reference_tokens.insert(reference_tokens.end(),
|
reference_tokens.insert(reference_tokens.end(), ptr.reference_tokens.begin(), ptr.reference_tokens.end());
|
||||||
ptr.reference_tokens.begin(),
|
|
||||||
ptr.reference_tokens.end());
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,8 +115,7 @@ class json_pointer
|
|||||||
|
|
||||||
/// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
|
/// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
|
||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
||||||
friend json_pointer operator/(const json_pointer& lhs,
|
friend json_pointer operator/(const json_pointer& lhs, const json_pointer& rhs)
|
||||||
const json_pointer& rhs)
|
|
||||||
{
|
{
|
||||||
return json_pointer(lhs) /= rhs;
|
return json_pointer(lhs) /= rhs;
|
||||||
}
|
}
|
||||||
@@ -359,17 +353,12 @@ class json_pointer
|
|||||||
if (ptr->is_null())
|
if (ptr->is_null())
|
||||||
{
|
{
|
||||||
// check if reference token is a number
|
// check if reference token is a number
|
||||||
const bool nums =
|
const bool nums = std::all_of(reference_token.begin(), reference_token.end(), [](const unsigned char x) {
|
||||||
std::all_of(reference_token.begin(), reference_token.end(),
|
|
||||||
[](const unsigned char x)
|
|
||||||
{
|
|
||||||
return std::isdigit(x);
|
return std::isdigit(x);
|
||||||
});
|
});
|
||||||
|
|
||||||
// change value to array for numbers or "-" or to object otherwise
|
// change value to array for numbers or "-" or to object otherwise
|
||||||
*ptr = (nums || reference_token == "-")
|
*ptr = (nums || reference_token == "-") ? detail::value_t::array : detail::value_t::object;
|
||||||
? detail::value_t::array
|
|
||||||
: detail::value_t::object;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ptr->type())
|
switch (ptr->type())
|
||||||
@@ -437,9 +426,10 @@ class json_pointer
|
|||||||
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
||||||
{
|
{
|
||||||
// "-" always fails the range check
|
// "-" always fails the range check
|
||||||
JSON_THROW(detail::out_of_range::create(402, detail::concat(
|
JSON_THROW(detail::out_of_range::create(
|
||||||
"array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
|
402,
|
||||||
") is out of range"), ptr));
|
detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"),
|
||||||
|
ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: at performs range check
|
// note: at performs range check
|
||||||
@@ -495,7 +485,10 @@ class json_pointer
|
|||||||
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
||||||
{
|
{
|
||||||
// "-" cannot be used for const access
|
// "-" cannot be used for const access
|
||||||
JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
|
JSON_THROW(detail::out_of_range::create(
|
||||||
|
402,
|
||||||
|
detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"),
|
||||||
|
ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// use unchecked array access
|
// use unchecked array access
|
||||||
@@ -544,9 +537,10 @@ class json_pointer
|
|||||||
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
||||||
{
|
{
|
||||||
// "-" always fails the range check
|
// "-" always fails the range check
|
||||||
JSON_THROW(detail::out_of_range::create(402, detail::concat(
|
JSON_THROW(detail::out_of_range::create(
|
||||||
"array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
|
402,
|
||||||
") is out of range"), ptr));
|
detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"),
|
||||||
|
ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: at performs range check
|
// note: at performs range check
|
||||||
@@ -676,7 +670,8 @@ class json_pointer
|
|||||||
// check if nonempty reference string begins with slash
|
// check if nonempty reference string begins with slash
|
||||||
if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
|
if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
|
||||||
{
|
{
|
||||||
JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
|
JSON_THROW(
|
||||||
|
detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract the reference tokens:
|
// extract the reference tokens:
|
||||||
@@ -700,16 +695,12 @@ class json_pointer
|
|||||||
auto reference_token = reference_string.substr(start, slash - start);
|
auto reference_token = reference_string.substr(start, slash - start);
|
||||||
|
|
||||||
// check reference tokens are properly escaped
|
// check reference tokens are properly escaped
|
||||||
for (std::size_t pos = reference_token.find_first_of('~');
|
for (std::size_t pos = reference_token.find_first_of('~'); pos != string_t::npos; pos = reference_token.find_first_of('~', pos + 1))
|
||||||
pos != string_t::npos;
|
|
||||||
pos = reference_token.find_first_of('~', pos + 1))
|
|
||||||
{
|
{
|
||||||
JSON_ASSERT(reference_token[pos] == '~');
|
JSON_ASSERT(reference_token[pos] == '~');
|
||||||
|
|
||||||
// ~ must be followed by 0 or 1
|
// ~ must be followed by 0 or 1
|
||||||
if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
|
if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 || (reference_token[pos + 1] != '0' && reference_token[pos + 1] != '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'", nullptr));
|
JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
|
||||||
}
|
}
|
||||||
@@ -732,9 +723,7 @@ class json_pointer
|
|||||||
@note Empty objects or arrays are flattened to `null`.
|
@note Empty objects or arrays are flattened to `null`.
|
||||||
*/
|
*/
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void flatten(const string_t& reference_string,
|
static void flatten(const string_t& reference_string, const BasicJsonType& value, BasicJsonType& result)
|
||||||
const BasicJsonType& value,
|
|
||||||
BasicJsonType& result)
|
|
||||||
{
|
{
|
||||||
switch (value.type())
|
switch (value.type())
|
||||||
{
|
{
|
||||||
@@ -750,8 +739,7 @@ class json_pointer
|
|||||||
// iterate array and use index as reference string
|
// iterate array and use index as reference string
|
||||||
for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)
|
for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)
|
||||||
{
|
{
|
||||||
flatten(detail::concat(reference_string, '/', std::to_string(i)),
|
flatten(detail::concat(reference_string, '/', std::to_string(i)), value.m_data.m_value.array->operator[](i), result);
|
||||||
value.m_data.m_value.array->operator[](i), result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -803,8 +791,7 @@ class json_pointer
|
|||||||
@throw type_error.313 if value cannot be unflattened
|
@throw type_error.313 if value cannot be unflattened
|
||||||
*/
|
*/
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static BasicJsonType
|
static BasicJsonType unflatten(const BasicJsonType& value)
|
||||||
unflatten(const BasicJsonType& value)
|
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
|
if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
|
||||||
{
|
{
|
||||||
@@ -875,49 +862,42 @@ class json_pointer
|
|||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
|
||||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||||
// NOLINTNEXTLINE(readability-redundant-declaration)
|
// NOLINTNEXTLINE(readability-redundant-declaration)
|
||||||
friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
|
friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs, const json_pointer<RefStringTypeRhs>& rhs) noexcept;
|
||||||
const json_pointer<RefStringTypeRhs>& rhs) noexcept;
|
|
||||||
|
|
||||||
/// @brief compares JSON pointer and string for equality
|
/// @brief compares JSON pointer and string for equality
|
||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
|
||||||
template<typename RefStringTypeLhs, typename StringType>
|
template<typename RefStringTypeLhs, typename StringType>
|
||||||
// NOLINTNEXTLINE(readability-redundant-declaration)
|
// NOLINTNEXTLINE(readability-redundant-declaration)
|
||||||
friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
|
friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs, const StringType& rhs);
|
||||||
const StringType& rhs);
|
|
||||||
|
|
||||||
/// @brief compares string and JSON pointer for equality
|
/// @brief compares string and JSON pointer for equality
|
||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
|
||||||
template<typename RefStringTypeRhs, typename StringType>
|
template<typename RefStringTypeRhs, typename StringType>
|
||||||
// NOLINTNEXTLINE(readability-redundant-declaration)
|
// NOLINTNEXTLINE(readability-redundant-declaration)
|
||||||
friend bool operator==(const StringType& lhs,
|
friend bool operator==(const StringType& lhs, const json_pointer<RefStringTypeRhs>& rhs);
|
||||||
const json_pointer<RefStringTypeRhs>& rhs);
|
|
||||||
|
|
||||||
/// @brief compares two JSON pointers for inequality
|
/// @brief compares two JSON pointers for inequality
|
||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
|
||||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||||
// NOLINTNEXTLINE(readability-redundant-declaration)
|
// NOLINTNEXTLINE(readability-redundant-declaration)
|
||||||
friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
|
friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs, const json_pointer<RefStringTypeRhs>& rhs) noexcept;
|
||||||
const json_pointer<RefStringTypeRhs>& rhs) noexcept;
|
|
||||||
|
|
||||||
/// @brief compares JSON pointer and string for inequality
|
/// @brief compares JSON pointer and string for inequality
|
||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
|
||||||
template<typename RefStringTypeLhs, typename StringType>
|
template<typename RefStringTypeLhs, typename StringType>
|
||||||
// NOLINTNEXTLINE(readability-redundant-declaration)
|
// NOLINTNEXTLINE(readability-redundant-declaration)
|
||||||
friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
|
friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs, const StringType& rhs);
|
||||||
const StringType& rhs);
|
|
||||||
|
|
||||||
/// @brief compares string and JSON pointer for inequality
|
/// @brief compares string and JSON pointer for inequality
|
||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/
|
||||||
template<typename RefStringTypeRhs, typename StringType>
|
template<typename RefStringTypeRhs, typename StringType>
|
||||||
// NOLINTNEXTLINE(readability-redundant-declaration)
|
// NOLINTNEXTLINE(readability-redundant-declaration)
|
||||||
friend bool operator!=(const StringType& lhs,
|
friend bool operator!=(const StringType& lhs, const json_pointer<RefStringTypeRhs>& rhs);
|
||||||
const json_pointer<RefStringTypeRhs>& rhs);
|
|
||||||
|
|
||||||
/// @brief compares two JSON pointer for less-than
|
/// @brief compares two JSON pointer for less-than
|
||||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||||
// NOLINTNEXTLINE(readability-redundant-declaration)
|
// NOLINTNEXTLINE(readability-redundant-declaration)
|
||||||
friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
|
friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs, const json_pointer<RefStringTypeRhs>& rhs) noexcept;
|
||||||
const json_pointer<RefStringTypeRhs>& rhs) noexcept;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -928,58 +908,47 @@ class json_pointer
|
|||||||
#if !JSON_HAS_THREE_WAY_COMPARISON
|
#if !JSON_HAS_THREE_WAY_COMPARISON
|
||||||
// functions cannot be defined inside class due to ODR violations
|
// functions cannot be defined inside class due to ODR violations
|
||||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||||
inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
|
inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs, const json_pointer<RefStringTypeRhs>& rhs) noexcept
|
||||||
const json_pointer<RefStringTypeRhs>& rhs) noexcept
|
|
||||||
{
|
{
|
||||||
return lhs.reference_tokens == rhs.reference_tokens;
|
return lhs.reference_tokens == rhs.reference_tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RefStringTypeLhs,
|
template<typename RefStringTypeLhs, typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
|
||||||
typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
|
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))
|
||||||
inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
|
inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs, const StringType& rhs)
|
||||||
const StringType& rhs)
|
|
||||||
{
|
{
|
||||||
return lhs == json_pointer<RefStringTypeLhs>(rhs);
|
return lhs == json_pointer<RefStringTypeLhs>(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RefStringTypeRhs,
|
template<typename RefStringTypeRhs, typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
|
||||||
typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
|
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))
|
||||||
inline bool operator==(const StringType& lhs,
|
inline bool operator==(const StringType& lhs, const json_pointer<RefStringTypeRhs>& rhs)
|
||||||
const json_pointer<RefStringTypeRhs>& rhs)
|
|
||||||
{
|
{
|
||||||
return json_pointer<RefStringTypeRhs>(lhs) == rhs;
|
return json_pointer<RefStringTypeRhs>(lhs) == rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||||
inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
|
inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs, const json_pointer<RefStringTypeRhs>& rhs) noexcept
|
||||||
const json_pointer<RefStringTypeRhs>& rhs) noexcept
|
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RefStringTypeLhs,
|
template<typename RefStringTypeLhs, typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
|
||||||
typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
|
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))
|
||||||
inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
|
inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs, const StringType& rhs)
|
||||||
const StringType& rhs)
|
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RefStringTypeRhs,
|
template<typename RefStringTypeRhs, typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
|
||||||
typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
|
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))
|
||||||
inline bool operator!=(const StringType& lhs,
|
inline bool operator!=(const StringType& lhs, const json_pointer<RefStringTypeRhs>& rhs)
|
||||||
const json_pointer<RefStringTypeRhs>& rhs)
|
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||||
inline bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
|
inline bool operator<(const json_pointer<RefStringTypeLhs>& lhs, const json_pointer<RefStringTypeRhs>& rhs) noexcept
|
||||||
const json_pointer<RefStringTypeRhs>& rhs) noexcept
|
|
||||||
{
|
{
|
||||||
return lhs.reference_tokens < rhs.reference_tokens;
|
return lhs.reference_tokens < rhs.reference_tokens;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,9 +36,7 @@ class json_ref
|
|||||||
: owned_value(init)
|
: owned_value(init)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <
|
template<class... Args, enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0>
|
||||||
class... Args,
|
|
||||||
enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
|
|
||||||
json_ref(Args&&... args)
|
json_ref(Args&&... args)
|
||||||
: owned_value(std::forward<Args>(args)...)
|
: owned_value(std::forward<Args>(args)...)
|
||||||
{}
|
{}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -28,8 +28,8 @@ using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::typ
|
|||||||
// the following utilities are natively available in C++14
|
// the following utilities are natively available in C++14
|
||||||
using std::enable_if_t;
|
using std::enable_if_t;
|
||||||
using std::index_sequence;
|
using std::index_sequence;
|
||||||
using std::make_index_sequence;
|
|
||||||
using std::index_sequence_for;
|
using std::index_sequence_for;
|
||||||
|
using std::make_index_sequence;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -103,8 +103,7 @@ struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
|
|||||||
template<typename T, size_t N>
|
template<typename T, size_t N>
|
||||||
struct Gen
|
struct Gen
|
||||||
{
|
{
|
||||||
using type =
|
using type = typename Extend<typename Gen<T, N / 2>::type, N / 2, N % 2>::type;
|
||||||
typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -146,8 +145,12 @@ using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// dispatch utility (taken from ranges-v3)
|
// dispatch utility (taken from ranges-v3)
|
||||||
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
|
template<unsigned N>
|
||||||
template<> struct priority_tag<0> {};
|
struct priority_tag : priority_tag<N - 1>
|
||||||
|
{};
|
||||||
|
template<>
|
||||||
|
struct priority_tag<0>
|
||||||
|
{};
|
||||||
|
|
||||||
// taken from ranges-v3
|
// taken from ranges-v3
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|||||||
@@ -27,10 +27,7 @@ struct nonesuch
|
|||||||
void operator=(nonesuch&&) = delete;
|
void operator=(nonesuch&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Default,
|
template<class Default, class AlwaysVoid, template<class...> class Op, class... Args>
|
||||||
class AlwaysVoid,
|
|
||||||
template<class...> class Op,
|
|
||||||
class... Args>
|
|
||||||
struct detector
|
struct detector
|
||||||
{
|
{
|
||||||
using value_t = std::false_type;
|
using value_t = std::false_type;
|
||||||
@@ -48,7 +45,8 @@ template<template<class...> class Op, class... Args>
|
|||||||
using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
|
using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
|
||||||
|
|
||||||
template<template<class...> class Op, class... Args>
|
template<template<class...> class Op, class... Args>
|
||||||
struct is_detected_lazy : is_detected<Op, Args...> { };
|
struct is_detected_lazy : is_detected<Op, Args...>
|
||||||
|
{};
|
||||||
|
|
||||||
template<template<class...> class Op, class... Args>
|
template<template<class...> class Op, class... Args>
|
||||||
using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
|
using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
|
||||||
@@ -63,8 +61,7 @@ template<class Expected, template<class...> class Op, class... Args>
|
|||||||
using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
|
using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
|
||||||
|
|
||||||
template<class To, template<class...> class Op, class... Args>
|
template<class To, template<class...> class Op, class... Args>
|
||||||
using is_detected_convertible =
|
using is_detected_convertible = std::is_convertible<detected_t<Op, Args...>, To>;
|
||||||
std::is_convertible<detected_t<Op, Args...>, To>;
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ namespace detail
|
|||||||
{
|
{
|
||||||
|
|
||||||
// dispatching helper struct
|
// dispatching helper struct
|
||||||
template <class T> struct identity_tag {};
|
template<class T>
|
||||||
|
struct identity_tag
|
||||||
|
{};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint> // size_t
|
#include <cstdint> // size_t
|
||||||
#include <utility> // declval
|
|
||||||
#include <string> // string
|
#include <string> // string
|
||||||
|
#include <utility> // declval
|
||||||
|
|
||||||
#include <nlohmann/detail/abi_macros.hpp>
|
#include <nlohmann/detail/abi_macros.hpp>
|
||||||
#include <nlohmann/detail/meta/detected.hpp>
|
#include <nlohmann/detail/meta/detected.hpp>
|
||||||
@@ -24,58 +24,47 @@ template<typename T>
|
|||||||
using null_function_t = decltype(std::declval<T&>().null());
|
using null_function_t = decltype(std::declval<T&>().null());
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using boolean_function_t =
|
using boolean_function_t = decltype(std::declval<T&>().boolean(std::declval<bool>()));
|
||||||
decltype(std::declval<T&>().boolean(std::declval<bool>()));
|
|
||||||
|
|
||||||
template<typename T, typename Integer>
|
template<typename T, typename Integer>
|
||||||
using number_integer_function_t =
|
using number_integer_function_t = decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
|
||||||
decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
|
|
||||||
|
|
||||||
template<typename T, typename Unsigned>
|
template<typename T, typename Unsigned>
|
||||||
using number_unsigned_function_t =
|
using number_unsigned_function_t = decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
|
||||||
decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
|
|
||||||
|
|
||||||
template<typename T, typename Float, typename String>
|
template<typename T, typename Float, typename String>
|
||||||
using number_float_function_t = decltype(std::declval<T&>().number_float(
|
using number_float_function_t = decltype(std::declval<T&>().number_float(std::declval<Float>(), std::declval<const String&>()));
|
||||||
std::declval<Float>(), std::declval<const String&>()));
|
|
||||||
|
|
||||||
template<typename T, typename String>
|
template<typename T, typename String>
|
||||||
using string_function_t =
|
using string_function_t = decltype(std::declval<T&>().string(std::declval<String&>()));
|
||||||
decltype(std::declval<T&>().string(std::declval<String&>()));
|
|
||||||
|
|
||||||
template<typename T, typename Binary>
|
template<typename T, typename Binary>
|
||||||
using binary_function_t =
|
using binary_function_t = decltype(std::declval<T&>().binary(std::declval<Binary&>()));
|
||||||
decltype(std::declval<T&>().binary(std::declval<Binary&>()));
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using start_object_function_t =
|
using start_object_function_t = decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
|
||||||
decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
|
|
||||||
|
|
||||||
template<typename T, typename String>
|
template<typename T, typename String>
|
||||||
using key_function_t =
|
using key_function_t = decltype(std::declval<T&>().key(std::declval<String&>()));
|
||||||
decltype(std::declval<T&>().key(std::declval<String&>()));
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using end_object_function_t = decltype(std::declval<T&>().end_object());
|
using end_object_function_t = decltype(std::declval<T&>().end_object());
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using start_array_function_t =
|
using start_array_function_t = decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
|
||||||
decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using end_array_function_t = decltype(std::declval<T&>().end_array());
|
using end_array_function_t = decltype(std::declval<T&>().end_array());
|
||||||
|
|
||||||
template<typename T, typename Exception>
|
template<typename T, typename Exception>
|
||||||
using parse_error_function_t = decltype(std::declval<T&>().parse_error(
|
using parse_error_function_t =
|
||||||
std::declval<std::size_t>(), std::declval<const std::string&>(),
|
decltype(std::declval<T&>().parse_error(std::declval<std::size_t>(), std::declval<const std::string&>(), std::declval<const Exception&>()));
|
||||||
std::declval<const Exception&>()));
|
|
||||||
|
|
||||||
template<typename SAX, typename BasicJsonType>
|
template<typename SAX, typename BasicJsonType>
|
||||||
struct is_sax
|
struct is_sax
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static_assert(is_basic_json<BasicJsonType>::value,
|
static_assert(is_basic_json<BasicJsonType>::value, "BasicJsonType must be of type basic_json<...>");
|
||||||
"BasicJsonType must be of type basic_json<...>");
|
|
||||||
|
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
@@ -86,27 +75,21 @@ struct is_sax
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr bool value =
|
static constexpr bool value =
|
||||||
is_detected_exact<bool, null_function_t, SAX>::value &&
|
is_detected_exact<bool, null_function_t, SAX>::value && is_detected_exact<bool, boolean_function_t, SAX>::value &&
|
||||||
is_detected_exact<bool, boolean_function_t, SAX>::value &&
|
|
||||||
is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
|
is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
|
||||||
is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
|
is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
|
||||||
is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
|
is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
|
||||||
is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
|
is_detected_exact<bool, string_function_t, SAX, string_t>::value && is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
|
||||||
is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
|
is_detected_exact<bool, start_object_function_t, SAX>::value && is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
|
||||||
is_detected_exact<bool, start_object_function_t, SAX>::value &&
|
is_detected_exact<bool, end_object_function_t, SAX>::value && is_detected_exact<bool, start_array_function_t, SAX>::value &&
|
||||||
is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
|
is_detected_exact<bool, end_array_function_t, SAX>::value && is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
|
||||||
is_detected_exact<bool, end_object_function_t, SAX>::value &&
|
|
||||||
is_detected_exact<bool, start_array_function_t, SAX>::value &&
|
|
||||||
is_detected_exact<bool, end_array_function_t, SAX>::value &&
|
|
||||||
is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename SAX, typename BasicJsonType>
|
template<typename SAX, typename BasicJsonType>
|
||||||
struct is_sax_static_asserts
|
struct is_sax_static_asserts
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static_assert(is_basic_json<BasicJsonType>::value,
|
static_assert(is_basic_json<BasicJsonType>::value, "BasicJsonType must be of type basic_json<...>");
|
||||||
"BasicJsonType must be of type basic_json<...>");
|
|
||||||
|
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
@@ -116,41 +99,23 @@ struct is_sax_static_asserts
|
|||||||
using exception_t = typename BasicJsonType::exception;
|
using exception_t = typename BasicJsonType::exception;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
|
static_assert(is_detected_exact<bool, null_function_t, SAX>::value, "Missing/invalid function: bool null()");
|
||||||
"Missing/invalid function: bool null()");
|
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value, "Missing/invalid function: bool boolean(bool)");
|
||||||
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
|
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value, "Missing/invalid function: bool boolean(bool)");
|
||||||
"Missing/invalid function: bool boolean(bool)");
|
static_assert(is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value,
|
||||||
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
|
|
||||||
"Missing/invalid function: bool boolean(bool)");
|
|
||||||
static_assert(
|
|
||||||
is_detected_exact<bool, number_integer_function_t, SAX,
|
|
||||||
number_integer_t>::value,
|
|
||||||
"Missing/invalid function: bool number_integer(number_integer_t)");
|
"Missing/invalid function: bool number_integer(number_integer_t)");
|
||||||
static_assert(
|
static_assert(is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value,
|
||||||
is_detected_exact<bool, number_unsigned_function_t, SAX,
|
|
||||||
number_unsigned_t>::value,
|
|
||||||
"Missing/invalid function: bool number_unsigned(number_unsigned_t)");
|
"Missing/invalid function: bool number_unsigned(number_unsigned_t)");
|
||||||
static_assert(is_detected_exact<bool, number_float_function_t, SAX,
|
static_assert(is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value,
|
||||||
number_float_t, string_t>::value,
|
|
||||||
"Missing/invalid function: bool number_float(number_float_t, const string_t&)");
|
"Missing/invalid function: bool number_float(number_float_t, const string_t&)");
|
||||||
static_assert(
|
static_assert(is_detected_exact<bool, string_function_t, SAX, string_t>::value, "Missing/invalid function: bool string(string_t&)");
|
||||||
is_detected_exact<bool, string_function_t, SAX, string_t>::value,
|
static_assert(is_detected_exact<bool, binary_function_t, SAX, binary_t>::value, "Missing/invalid function: bool binary(binary_t&)");
|
||||||
"Missing/invalid function: bool string(string_t&)");
|
static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value, "Missing/invalid function: bool start_object(std::size_t)");
|
||||||
static_assert(
|
static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value, "Missing/invalid function: bool key(string_t&)");
|
||||||
is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
|
static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value, "Missing/invalid function: bool end_object()");
|
||||||
"Missing/invalid function: bool binary(binary_t&)");
|
static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value, "Missing/invalid function: bool start_array(std::size_t)");
|
||||||
static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
|
static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value, "Missing/invalid function: bool end_array()");
|
||||||
"Missing/invalid function: bool start_object(std::size_t)");
|
static_assert(is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
|
||||||
static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
|
|
||||||
"Missing/invalid function: bool key(string_t&)");
|
|
||||||
static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
|
|
||||||
"Missing/invalid function: bool end_object()");
|
|
||||||
static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
|
|
||||||
"Missing/invalid function: bool start_array(std::size_t)");
|
|
||||||
static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
|
|
||||||
"Missing/invalid function: bool end_array()");
|
|
||||||
static_assert(
|
|
||||||
is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
|
|
||||||
"Missing/invalid function: bool parse_error(std::size_t, const "
|
"Missing/invalid function: bool parse_error(std::size_t, const "
|
||||||
"std::string&, const exception&)");
|
"std::string&, const exception&)");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <limits> // numeric_limits
|
#include <limits> // numeric_limits
|
||||||
|
#include <string> // char_traits
|
||||||
|
#include <tuple> // tuple
|
||||||
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
|
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
|
||||||
#include <utility> // declval
|
#include <utility> // declval
|
||||||
#include <tuple> // tuple
|
|
||||||
#include <string> // char_traits
|
|
||||||
|
|
||||||
#include <nlohmann/detail/iterators/iterator_traits.hpp>
|
#include <nlohmann/detail/iterators/iterator_traits.hpp>
|
||||||
#include <nlohmann/detail/macro_scope.hpp>
|
#include <nlohmann/detail/macro_scope.hpp>
|
||||||
@@ -47,19 +47,22 @@ namespace detail
|
|||||||
// In this case, T has to be properly CV-qualified to constraint the function arguments
|
// In this case, T has to be properly CV-qualified to constraint the function arguments
|
||||||
// (e.g. to_json(BasicJsonType&, const T&))
|
// (e.g. to_json(BasicJsonType&, const T&))
|
||||||
|
|
||||||
template<typename> struct is_basic_json : std::false_type {};
|
template<typename>
|
||||||
|
struct is_basic_json : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
|
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
// used by exceptions create() member functions
|
// used by exceptions create() member functions
|
||||||
// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
|
// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
|
||||||
// false_type otherwise
|
// false_type otherwise
|
||||||
template<typename BasicJsonContext>
|
template<typename BasicJsonContext>
|
||||||
struct is_basic_json_context :
|
struct is_basic_json_context
|
||||||
std::integral_constant < bool,
|
: std::integral_constant<bool,
|
||||||
is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
|
is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value ||
|
||||||
|| std::is_same<BasicJsonContext, std::nullptr_t>::value >
|
std::is_same<BasicJsonContext, std::nullptr_t>::value>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
//////////////////////
|
//////////////////////
|
||||||
@@ -70,10 +73,12 @@ template<typename>
|
|||||||
class json_ref;
|
class json_ref;
|
||||||
|
|
||||||
template<typename>
|
template<typename>
|
||||||
struct is_json_ref : std::false_type {};
|
struct is_json_ref : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_json_ref<json_ref<T>> : std::true_type {};
|
struct is_json_ref<json_ref<T>> : std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
// aliases for detected //
|
// aliases for detected //
|
||||||
@@ -111,7 +116,8 @@ using get_template_function = decltype(std::declval<T>().template get<U>());
|
|||||||
|
|
||||||
// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
|
// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
|
||||||
template<typename BasicJsonType, typename T, typename = void>
|
template<typename BasicJsonType, typename T, typename = void>
|
||||||
struct has_from_json : std::false_type {};
|
struct has_from_json : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
// trait checking if j.get<T> is valid
|
// trait checking if j.get<T> is valid
|
||||||
// use this trait instead of std::is_constructible or std::is_convertible,
|
// use this trait instead of std::is_constructible or std::is_convertible,
|
||||||
@@ -128,46 +134,43 @@ struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value
|
|||||||
{
|
{
|
||||||
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
||||||
|
|
||||||
static constexpr bool value =
|
static constexpr bool value = is_detected_exact<void, from_json_function, serializer, const BasicJsonType&, T&>::value;
|
||||||
is_detected_exact<void, from_json_function, serializer,
|
|
||||||
const BasicJsonType&, T&>::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
|
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
|
||||||
// this overload is used for non-default-constructible user-defined-types
|
// this overload is used for non-default-constructible user-defined-types
|
||||||
template<typename BasicJsonType, typename T, typename = void>
|
template<typename BasicJsonType, typename T, typename = void>
|
||||||
struct has_non_default_from_json : std::false_type {};
|
struct has_non_default_from_json : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T>
|
template<typename BasicJsonType, typename T>
|
||||||
struct has_non_default_from_json<BasicJsonType, T, enable_if_t<!is_basic_json<T>::value>>
|
struct has_non_default_from_json<BasicJsonType, T, enable_if_t<!is_basic_json<T>::value>>
|
||||||
{
|
{
|
||||||
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
||||||
|
|
||||||
static constexpr bool value =
|
static constexpr bool value = is_detected_exact<T, from_json_function, serializer, const BasicJsonType&>::value;
|
||||||
is_detected_exact<T, from_json_function, serializer,
|
|
||||||
const BasicJsonType&>::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
|
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
|
||||||
// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
|
// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
|
||||||
template<typename BasicJsonType, typename T, typename = void>
|
template<typename BasicJsonType, typename T, typename = void>
|
||||||
struct has_to_json : std::false_type {};
|
struct has_to_json : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T>
|
template<typename BasicJsonType, typename T>
|
||||||
struct has_to_json<BasicJsonType, T, enable_if_t<!is_basic_json<T>::value>>
|
struct has_to_json<BasicJsonType, T, enable_if_t<!is_basic_json<T>::value>>
|
||||||
{
|
{
|
||||||
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
using serializer = typename BasicJsonType::template json_serializer<T, void>;
|
||||||
|
|
||||||
static constexpr bool value =
|
static constexpr bool value = is_detected_exact<void, to_json_function, serializer, BasicJsonType&, T>::value;
|
||||||
is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
|
|
||||||
T>::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using detect_key_compare = typename T::key_compare;
|
using detect_key_compare = typename T::key_compare;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
|
struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value>
|
||||||
|
{};
|
||||||
|
|
||||||
// obtains the actual object key comparator
|
// obtains the actual object key comparator
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
@@ -175,8 +178,7 @@ struct actual_object_comparator
|
|||||||
{
|
{
|
||||||
using object_t = typename BasicJsonType::object_t;
|
using object_t = typename BasicJsonType::object_t;
|
||||||
using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
|
using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
|
||||||
using type = typename std::conditional < has_key_compare<object_t>::value,
|
using type = typename std::conditional<has_key_compare<object_t>::value, typename object_t::key_compare, object_comparator_t>::type;
|
||||||
typename object_t::key_compare, object_comparator_t>::type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
@@ -244,54 +246,67 @@ struct char_traits<signed char> : std::char_traits<char>
|
|||||||
///////////////////
|
///////////////////
|
||||||
|
|
||||||
// https://en.cppreference.com/w/cpp/types/conjunction
|
// https://en.cppreference.com/w/cpp/types/conjunction
|
||||||
template<class...> struct conjunction : std::true_type { };
|
template<class...>
|
||||||
template<class B> struct conjunction<B> : B { };
|
struct conjunction : std::true_type
|
||||||
|
{};
|
||||||
|
template<class B>
|
||||||
|
struct conjunction<B> : B
|
||||||
|
{};
|
||||||
template<class B, class... Bn>
|
template<class B, class... Bn>
|
||||||
struct conjunction<B, Bn...>
|
struct conjunction<B, Bn...> : std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type
|
||||||
: std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
|
{};
|
||||||
|
|
||||||
// https://en.cppreference.com/w/cpp/types/negation
|
// https://en.cppreference.com/w/cpp/types/negation
|
||||||
template<class B> struct negation : std::integral_constant < bool, !B::value > { };
|
template<class B>
|
||||||
|
struct negation : std::integral_constant<bool, !B::value>
|
||||||
|
{};
|
||||||
|
|
||||||
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
|
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
|
||||||
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
|
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
|
||||||
// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
|
// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_default_constructible : std::is_default_constructible<T> {};
|
struct is_default_constructible : std::is_default_constructible<T>
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct is_default_constructible<std::pair<T1, T2>>
|
struct is_default_constructible<std::pair<T1, T2>> : conjunction<is_default_constructible<T1>, is_default_constructible<T2>>
|
||||||
: conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
|
{};
|
||||||
|
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct is_default_constructible<const std::pair<T1, T2>>
|
struct is_default_constructible<const std::pair<T1, T2>> : conjunction<is_default_constructible<T1>, is_default_constructible<T2>>
|
||||||
: conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
|
{};
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
struct is_default_constructible<std::tuple<Ts...>>
|
struct is_default_constructible<std::tuple<Ts...>> : conjunction<is_default_constructible<Ts>...>
|
||||||
: conjunction<is_default_constructible<Ts>...> {};
|
{};
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
struct is_default_constructible<const std::tuple<Ts...>>
|
struct is_default_constructible<const std::tuple<Ts...>> : conjunction<is_default_constructible<Ts>...>
|
||||||
: conjunction<is_default_constructible<Ts>...> {};
|
{};
|
||||||
|
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
struct is_constructible : std::is_constructible<T, Args...> {};
|
struct is_constructible : std::is_constructible<T, Args...>
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
|
struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>>
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
|
struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>>
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
|
struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>>
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
|
struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>>
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T, typename = void>
|
template<typename T, typename = void>
|
||||||
struct is_iterator_traits : std::false_type {};
|
struct is_iterator_traits : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_iterator_traits<iterator_traits<T>>
|
struct is_iterator_traits<iterator_traits<T>>
|
||||||
@@ -300,11 +315,8 @@ struct is_iterator_traits<iterator_traits<T>>
|
|||||||
using traits = iterator_traits<T>;
|
using traits = iterator_traits<T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr auto value =
|
static constexpr auto value = is_detected<value_type_t, traits>::value && is_detected<difference_type_t, traits>::value &&
|
||||||
is_detected<value_type_t, traits>::value &&
|
is_detected<pointer_t, traits>::value && is_detected<iterator_category_t, traits>::value &&
|
||||||
is_detected<difference_type_t, traits>::value &&
|
|
||||||
is_detected<pointer_t, traits>::value &&
|
|
||||||
is_detected<iterator_category_t, traits>::value &&
|
|
||||||
is_detected<reference_t, traits>::value;
|
is_detected<reference_t, traits>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -320,8 +332,7 @@ struct is_range
|
|||||||
// to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
|
// to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
|
||||||
// and https://en.cppreference.com/w/cpp/iterator/sentinel_for
|
// and https://en.cppreference.com/w/cpp/iterator/sentinel_for
|
||||||
// but reimplementing these would be too much work, as a lot of other concepts are used underneath
|
// but reimplementing these would be too much work, as a lot of other concepts are used underneath
|
||||||
static constexpr auto is_iterator_begin =
|
static constexpr auto is_iterator_begin = is_iterator_traits<iterator_traits<iterator>>::value;
|
||||||
is_iterator_traits<iterator_traits<iterator>>::value;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
|
static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
|
||||||
@@ -338,73 +349,62 @@ using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;
|
|||||||
// and is written by Xiang Fan who agreed to using it in this library.
|
// and is written by Xiang Fan who agreed to using it in this library.
|
||||||
|
|
||||||
template<typename T, typename = void>
|
template<typename T, typename = void>
|
||||||
struct is_complete_type : std::false_type {};
|
struct is_complete_type : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
|
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleObjectType,
|
template<typename BasicJsonType, typename CompatibleObjectType, typename = void>
|
||||||
typename = void>
|
struct is_compatible_object_type_impl : std::false_type
|
||||||
struct is_compatible_object_type_impl : std::false_type {};
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleObjectType>
|
template<typename BasicJsonType, typename CompatibleObjectType>
|
||||||
struct is_compatible_object_type_impl<
|
struct is_compatible_object_type_impl<
|
||||||
BasicJsonType, CompatibleObjectType,
|
BasicJsonType,
|
||||||
enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
|
CompatibleObjectType,
|
||||||
is_detected<key_type_t, CompatibleObjectType>::value >>
|
enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value && is_detected<key_type_t, CompatibleObjectType>::value>>
|
||||||
{
|
{
|
||||||
using object_t = typename BasicJsonType::object_t;
|
using object_t = typename BasicJsonType::object_t;
|
||||||
|
|
||||||
// macOS's is_constructible does not play well with nonesuch...
|
// macOS's is_constructible does not play well with nonesuch...
|
||||||
static constexpr bool value =
|
static constexpr bool value = is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value &&
|
||||||
is_constructible<typename object_t::key_type,
|
is_constructible<typename object_t::mapped_type, typename CompatibleObjectType::mapped_type>::value;
|
||||||
typename CompatibleObjectType::key_type>::value &&
|
|
||||||
is_constructible<typename object_t::mapped_type,
|
|
||||||
typename CompatibleObjectType::mapped_type>::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleObjectType>
|
template<typename BasicJsonType, typename CompatibleObjectType>
|
||||||
struct is_compatible_object_type
|
struct is_compatible_object_type : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType>
|
||||||
: is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleObjectType,
|
template<typename BasicJsonType, typename ConstructibleObjectType, typename = void>
|
||||||
typename = void>
|
struct is_constructible_object_type_impl : std::false_type
|
||||||
struct is_constructible_object_type_impl : std::false_type {};
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleObjectType>
|
template<typename BasicJsonType, typename ConstructibleObjectType>
|
||||||
struct is_constructible_object_type_impl<
|
struct is_constructible_object_type_impl<
|
||||||
BasicJsonType, ConstructibleObjectType,
|
BasicJsonType,
|
||||||
enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
|
ConstructibleObjectType,
|
||||||
is_detected<key_type_t, ConstructibleObjectType>::value >>
|
enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value && is_detected<key_type_t, ConstructibleObjectType>::value>>
|
||||||
{
|
{
|
||||||
using object_t = typename BasicJsonType::object_t;
|
using object_t = typename BasicJsonType::object_t;
|
||||||
|
|
||||||
static constexpr bool value =
|
static constexpr bool value = (is_default_constructible<ConstructibleObjectType>::value &&
|
||||||
(is_default_constructible<ConstructibleObjectType>::value &&
|
(std::is_move_assignable<ConstructibleObjectType>::value || std::is_copy_assignable<ConstructibleObjectType>::value) &&
|
||||||
(std::is_move_assignable<ConstructibleObjectType>::value ||
|
(is_constructible<typename ConstructibleObjectType::key_type, typename object_t::key_type>::value &&
|
||||||
std::is_copy_assignable<ConstructibleObjectType>::value) &&
|
std::is_same<typename object_t::mapped_type, typename ConstructibleObjectType::mapped_type>::value)) ||
|
||||||
(is_constructible<typename ConstructibleObjectType::key_type,
|
(has_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type>::value ||
|
||||||
typename object_t::key_type>::value &&
|
has_non_default_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type>::value);
|
||||||
std::is_same <
|
|
||||||
typename object_t::mapped_type,
|
|
||||||
typename ConstructibleObjectType::mapped_type >::value)) ||
|
|
||||||
(has_from_json<BasicJsonType,
|
|
||||||
typename ConstructibleObjectType::mapped_type>::value ||
|
|
||||||
has_non_default_from_json <
|
|
||||||
BasicJsonType,
|
|
||||||
typename ConstructibleObjectType::mapped_type >::value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleObjectType>
|
template<typename BasicJsonType, typename ConstructibleObjectType>
|
||||||
struct is_constructible_object_type
|
struct is_constructible_object_type : is_constructible_object_type_impl<BasicJsonType, ConstructibleObjectType>
|
||||||
: is_constructible_object_type_impl<BasicJsonType,
|
{};
|
||||||
ConstructibleObjectType> {};
|
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleStringType>
|
template<typename BasicJsonType, typename CompatibleStringType>
|
||||||
struct is_compatible_string_type
|
struct is_compatible_string_type
|
||||||
{
|
{
|
||||||
static constexpr auto value =
|
static constexpr auto value = is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
|
||||||
is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleStringType>
|
template<typename BasicJsonType, typename ConstructibleStringType>
|
||||||
@@ -417,133 +417,116 @@ struct is_constructible_string_type
|
|||||||
using laundered_type = ConstructibleStringType;
|
using laundered_type = ConstructibleStringType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static constexpr auto value =
|
static constexpr auto value = conjunction<is_constructible<laundered_type, typename BasicJsonType::string_t>,
|
||||||
conjunction <
|
is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, laundered_type>>::value;
|
||||||
is_constructible<laundered_type, typename BasicJsonType::string_t>,
|
|
||||||
is_detected_exact<typename BasicJsonType::string_t::value_type,
|
|
||||||
value_type_t, laundered_type >>::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
|
template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
|
||||||
struct is_compatible_array_type_impl : std::false_type {};
|
struct is_compatible_array_type_impl : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleArrayType>
|
template<typename BasicJsonType, typename CompatibleArrayType>
|
||||||
struct is_compatible_array_type_impl <
|
struct is_compatible_array_type_impl<BasicJsonType,
|
||||||
BasicJsonType, CompatibleArrayType,
|
CompatibleArrayType,
|
||||||
enable_if_t <
|
enable_if_t<is_detected<iterator_t, CompatibleArrayType>::value &&
|
||||||
is_detected<iterator_t, CompatibleArrayType>::value&&
|
|
||||||
is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value &&
|
is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value &&
|
||||||
// special case for types like std::filesystem::path whose iterator's value_type are themselves
|
// special case for types like std::filesystem::path whose iterator's value_type are themselves
|
||||||
// c.f. https://github.com/nlohmann/json/pull/3073
|
// c.f. https://github.com/nlohmann/json/pull/3073
|
||||||
!std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value>>
|
!std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value>>
|
||||||
{
|
{
|
||||||
static constexpr bool value =
|
static constexpr bool value = is_constructible<BasicJsonType, range_value_t<CompatibleArrayType>>::value;
|
||||||
is_constructible<BasicJsonType,
|
|
||||||
range_value_t<CompatibleArrayType>>::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleArrayType>
|
template<typename BasicJsonType, typename CompatibleArrayType>
|
||||||
struct is_compatible_array_type
|
struct is_compatible_array_type : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType>
|
||||||
: is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
|
template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
|
||||||
struct is_constructible_array_type_impl : std::false_type {};
|
struct is_constructible_array_type_impl : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename ConstructibleArrayType>
|
||||||
|
struct is_constructible_array_type_impl<BasicJsonType,
|
||||||
|
ConstructibleArrayType,
|
||||||
|
enable_if_t<std::is_same<ConstructibleArrayType, typename BasicJsonType::value_type>::value>> : std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleArrayType>
|
template<typename BasicJsonType, typename ConstructibleArrayType>
|
||||||
struct is_constructible_array_type_impl<
|
struct is_constructible_array_type_impl<
|
||||||
BasicJsonType, ConstructibleArrayType,
|
BasicJsonType,
|
||||||
enable_if_t<std::is_same<ConstructibleArrayType,
|
ConstructibleArrayType,
|
||||||
typename BasicJsonType::value_type>::value >>
|
enable_if_t<!std::is_same<ConstructibleArrayType, typename BasicJsonType::value_type>::value &&
|
||||||
: std::true_type {};
|
!is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value && is_default_constructible<ConstructibleArrayType>::value &&
|
||||||
|
(std::is_move_assignable<ConstructibleArrayType>::value || std::is_copy_assignable<ConstructibleArrayType>::value) &&
|
||||||
template<typename BasicJsonType, typename ConstructibleArrayType>
|
|
||||||
struct is_constructible_array_type_impl <
|
|
||||||
BasicJsonType, ConstructibleArrayType,
|
|
||||||
enable_if_t < !std::is_same<ConstructibleArrayType,
|
|
||||||
typename BasicJsonType::value_type>::value&&
|
|
||||||
!is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
|
|
||||||
is_default_constructible<ConstructibleArrayType>::value&&
|
|
||||||
(std::is_move_assignable<ConstructibleArrayType>::value ||
|
|
||||||
std::is_copy_assignable<ConstructibleArrayType>::value)&&
|
|
||||||
is_detected<iterator_t, ConstructibleArrayType>::value &&
|
is_detected<iterator_t, ConstructibleArrayType>::value &&
|
||||||
is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value &&
|
is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value &&
|
||||||
is_detected<range_value_t, ConstructibleArrayType>::value &&
|
is_detected<range_value_t, ConstructibleArrayType>::value &&
|
||||||
// special case for types like std::filesystem::path whose iterator's value_type are themselves
|
// special case for types like std::filesystem::path whose iterator's value_type are themselves
|
||||||
// c.f. https://github.com/nlohmann/json/pull/3073
|
// c.f. https://github.com/nlohmann/json/pull/3073
|
||||||
!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value &&
|
!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value &&
|
||||||
is_complete_type <
|
is_complete_type<detected_t<range_value_t, ConstructibleArrayType>>::value>>
|
||||||
detected_t<range_value_t, ConstructibleArrayType >>::value >>
|
|
||||||
{
|
{
|
||||||
using value_type = range_value_t<ConstructibleArrayType>;
|
using value_type = range_value_t<ConstructibleArrayType>;
|
||||||
|
|
||||||
static constexpr bool value =
|
static constexpr bool value = std::is_same<value_type, typename BasicJsonType::array_t::value_type>::value ||
|
||||||
std::is_same<value_type,
|
has_from_json<BasicJsonType, value_type>::value || has_non_default_from_json<BasicJsonType, value_type>::value;
|
||||||
typename BasicJsonType::array_t::value_type>::value ||
|
|
||||||
has_from_json<BasicJsonType,
|
|
||||||
value_type>::value ||
|
|
||||||
has_non_default_from_json <
|
|
||||||
BasicJsonType,
|
|
||||||
value_type >::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleArrayType>
|
template<typename BasicJsonType, typename ConstructibleArrayType>
|
||||||
struct is_constructible_array_type
|
struct is_constructible_array_type : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType>
|
||||||
: is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
|
{};
|
||||||
|
|
||||||
template<typename RealIntegerType, typename CompatibleNumberIntegerType,
|
template<typename RealIntegerType, typename CompatibleNumberIntegerType, typename = void>
|
||||||
typename = void>
|
struct is_compatible_integer_type_impl : std::false_type
|
||||||
struct is_compatible_integer_type_impl : std::false_type {};
|
{};
|
||||||
|
|
||||||
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
|
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
|
||||||
struct is_compatible_integer_type_impl <
|
struct is_compatible_integer_type_impl<RealIntegerType,
|
||||||
RealIntegerType, CompatibleNumberIntegerType,
|
CompatibleNumberIntegerType,
|
||||||
enable_if_t < std::is_integral<RealIntegerType>::value&&
|
enable_if_t<std::is_integral<RealIntegerType>::value && std::is_integral<CompatibleNumberIntegerType>::value &&
|
||||||
std::is_integral<CompatibleNumberIntegerType>::value&&
|
|
||||||
!std::is_same<bool, CompatibleNumberIntegerType>::value>>
|
!std::is_same<bool, CompatibleNumberIntegerType>::value>>
|
||||||
{
|
{
|
||||||
// is there an assert somewhere on overflows?
|
// is there an assert somewhere on overflows?
|
||||||
using RealLimits = std::numeric_limits<RealIntegerType>;
|
using RealLimits = std::numeric_limits<RealIntegerType>;
|
||||||
using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
|
using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
|
||||||
|
|
||||||
static constexpr auto value =
|
static constexpr auto value = is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value && CompatibleLimits::is_integer &&
|
||||||
is_constructible<RealIntegerType,
|
|
||||||
CompatibleNumberIntegerType>::value &&
|
|
||||||
CompatibleLimits::is_integer &&
|
|
||||||
RealLimits::is_signed == CompatibleLimits::is_signed;
|
RealLimits::is_signed == CompatibleLimits::is_signed;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
|
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
|
||||||
struct is_compatible_integer_type
|
struct is_compatible_integer_type : is_compatible_integer_type_impl<RealIntegerType, CompatibleNumberIntegerType>
|
||||||
: is_compatible_integer_type_impl<RealIntegerType,
|
{};
|
||||||
CompatibleNumberIntegerType> {};
|
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleType, typename = void>
|
template<typename BasicJsonType, typename CompatibleType, typename = void>
|
||||||
struct is_compatible_type_impl: std::false_type {};
|
struct is_compatible_type_impl : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleType>
|
template<typename BasicJsonType, typename CompatibleType>
|
||||||
struct is_compatible_type_impl <
|
struct is_compatible_type_impl<BasicJsonType, CompatibleType, enable_if_t<is_complete_type<CompatibleType>::value>>
|
||||||
BasicJsonType, CompatibleType,
|
|
||||||
enable_if_t<is_complete_type<CompatibleType>::value >>
|
|
||||||
{
|
{
|
||||||
static constexpr bool value =
|
static constexpr bool value = has_to_json<BasicJsonType, CompatibleType>::value;
|
||||||
has_to_json<BasicJsonType, CompatibleType>::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename CompatibleType>
|
template<typename BasicJsonType, typename CompatibleType>
|
||||||
struct is_compatible_type
|
struct is_compatible_type : is_compatible_type_impl<BasicJsonType, CompatibleType>
|
||||||
: is_compatible_type_impl<BasicJsonType, CompatibleType> {};
|
{};
|
||||||
|
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct is_constructible_tuple : std::false_type {};
|
struct is_constructible_tuple : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T1, typename... Args>
|
template<typename T1, typename... Args>
|
||||||
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
|
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...>
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T>
|
template<typename BasicJsonType, typename T>
|
||||||
struct is_json_iterator_of : std::false_type {};
|
struct is_json_iterator_of : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
|
struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
|
struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
|
||||||
@@ -551,38 +534,45 @@ struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator
|
|||||||
|
|
||||||
// checks if a given type T is a template specialization of Primary
|
// checks if a given type T is a template specialization of Primary
|
||||||
template<template<typename...> class Primary, typename T>
|
template<template<typename...> class Primary, typename T>
|
||||||
struct is_specialization_of : std::false_type {};
|
struct is_specialization_of : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<template<typename...> class Primary, typename... Args>
|
template<template<typename...> class Primary, typename... Args>
|
||||||
struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
|
struct is_specialization_of<Primary, Primary<Args...>> : std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using is_json_pointer = is_specialization_of<::nlohmann::json_pointer, uncvref_t<T>>;
|
using is_json_pointer = is_specialization_of<::nlohmann::json_pointer, uncvref_t<T>>;
|
||||||
|
|
||||||
// checks if A and B are comparable using Compare functor
|
// checks if A and B are comparable using Compare functor
|
||||||
template<typename Compare, typename A, typename B, typename = void>
|
template<typename Compare, typename A, typename B, typename = void>
|
||||||
struct is_comparable : std::false_type {};
|
struct is_comparable : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename Compare, typename A, typename B>
|
template<typename Compare, typename A, typename B>
|
||||||
struct is_comparable<Compare, A, B, void_t<
|
struct is_comparable<
|
||||||
decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
|
Compare,
|
||||||
decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
|
A,
|
||||||
>> : std::true_type {};
|
B,
|
||||||
|
void_t<decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())), decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))>>
|
||||||
|
: std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using detect_is_transparent = typename T::is_transparent;
|
using detect_is_transparent = typename T::is_transparent;
|
||||||
|
|
||||||
// type trait to check if KeyType can be used as object key (without a BasicJsonType)
|
// type trait to check if KeyType can be used as object key (without a BasicJsonType)
|
||||||
// see is_usable_as_basic_json_key_type below
|
// see is_usable_as_basic_json_key_type below
|
||||||
template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
|
template<typename Comparator,
|
||||||
bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
|
typename ObjectKeyType,
|
||||||
using is_usable_as_key_type = typename std::conditional <
|
typename KeyTypeCVRef,
|
||||||
is_comparable<Comparator, ObjectKeyType, KeyTypeCVRef>::value
|
bool RequireTransparentComparator = true,
|
||||||
&& !(ExcludeObjectKeyType && std::is_same<KeyType,
|
bool ExcludeObjectKeyType = RequireTransparentComparator,
|
||||||
ObjectKeyType>::value)
|
typename KeyType = uncvref_t<KeyTypeCVRef>>
|
||||||
&& (!RequireTransparentComparator
|
using is_usable_as_key_type =
|
||||||
|| is_detected <detect_is_transparent, Comparator>::value)
|
typename std::conditional<is_comparable<Comparator, ObjectKeyType, KeyTypeCVRef>::value &&
|
||||||
&& !is_json_pointer<KeyType>::value,
|
!(ExcludeObjectKeyType && std::is_same<KeyType, ObjectKeyType>::value) &&
|
||||||
|
(!RequireTransparentComparator || is_detected<detect_is_transparent, Comparator>::value) && !is_json_pointer<KeyType>::value,
|
||||||
std::true_type,
|
std::true_type,
|
||||||
std::false_type>::type;
|
std::false_type>::type;
|
||||||
|
|
||||||
@@ -592,13 +582,17 @@ using is_usable_as_key_type = typename std::conditional <
|
|||||||
// - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
|
// - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
|
||||||
// - the comparator is transparent or RequireTransparentComparator is false
|
// - the comparator is transparent or RequireTransparentComparator is false
|
||||||
// - KeyType is not a JSON iterator or json_pointer
|
// - KeyType is not a JSON iterator or json_pointer
|
||||||
template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
|
template<typename BasicJsonType,
|
||||||
bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
|
typename KeyTypeCVRef,
|
||||||
using is_usable_as_basic_json_key_type = typename std::conditional <
|
bool RequireTransparentComparator = true,
|
||||||
is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
|
bool ExcludeObjectKeyType = RequireTransparentComparator,
|
||||||
typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
|
typename KeyType = uncvref_t<KeyTypeCVRef>>
|
||||||
RequireTransparentComparator, ExcludeObjectKeyType>::value
|
using is_usable_as_basic_json_key_type = typename std::conditional<is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
|
||||||
&& !is_json_iterator_of<BasicJsonType, KeyType>::value,
|
typename BasicJsonType::object_t::key_type,
|
||||||
|
KeyTypeCVRef,
|
||||||
|
RequireTransparentComparator,
|
||||||
|
ExcludeObjectKeyType>::value &&
|
||||||
|
!is_json_iterator_of<BasicJsonType, KeyType>::value,
|
||||||
std::true_type,
|
std::true_type,
|
||||||
std::false_type>::type;
|
std::false_type>::type;
|
||||||
|
|
||||||
@@ -607,12 +601,8 @@ using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(st
|
|||||||
|
|
||||||
// type trait to check if object_t has an erase() member functions accepting KeyType
|
// type trait to check if object_t has an erase() member functions accepting KeyType
|
||||||
template<typename BasicJsonType, typename KeyType>
|
template<typename BasicJsonType, typename KeyType>
|
||||||
using has_erase_with_key_type = typename std::conditional <
|
using has_erase_with_key_type =
|
||||||
is_detected <
|
typename std::conditional<is_detected<detect_erase_with_key_type, typename BasicJsonType::object_t, KeyType>::value, std::true_type, std::false_type>::type;
|
||||||
detect_erase_with_key_type,
|
|
||||||
typename BasicJsonType::object_t, KeyType >::value,
|
|
||||||
std::true_type,
|
|
||||||
std::false_type >::type;
|
|
||||||
|
|
||||||
// a naive helper to check if a type is an ordered_map (exploits the fact that
|
// a naive helper to check if a type is an ordered_map (exploits the fact that
|
||||||
// ordered_map inherits capacity() from std::vector)
|
// ordered_map inherits capacity() from std::vector)
|
||||||
@@ -626,10 +616,15 @@ struct is_ordered_map
|
|||||||
char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename C> static one test( decltype(&C::capacity) ) ;
|
template<typename C>
|
||||||
template <typename C> static two test(...);
|
static one test(decltype(&C::capacity));
|
||||||
|
template<typename C>
|
||||||
|
static two test(...);
|
||||||
|
|
||||||
enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
enum
|
||||||
|
{
|
||||||
|
value = sizeof(test<T>(nullptr)) == sizeof(char)
|
||||||
|
}; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
};
|
};
|
||||||
|
|
||||||
// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
|
// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
|
||||||
@@ -656,17 +651,14 @@ using all_unsigned = conjunction<std::is_unsigned<Types>...>;
|
|||||||
|
|
||||||
// there's a disjunction trait in another PR; replace when merged
|
// there's a disjunction trait in another PR; replace when merged
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
using same_sign = std::integral_constant < bool,
|
using same_sign = std::integral_constant<bool, all_signed<Types...>::value || all_unsigned<Types...>::value>;
|
||||||
all_signed<Types...>::value || all_unsigned<Types...>::value >;
|
|
||||||
|
|
||||||
template<typename OfType, typename T>
|
template<typename OfType, typename T>
|
||||||
using never_out_of_range = std::integral_constant < bool,
|
using never_out_of_range =
|
||||||
(std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
|
std::integral_constant<bool,
|
||||||
|| (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
|
(std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType))) || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T))>;
|
||||||
|
|
||||||
template<typename OfType, typename T,
|
template<typename OfType, typename T, bool OfTypeSigned = std::is_signed<OfType>::value, bool TSigned = std::is_signed<T>::value>
|
||||||
bool OfTypeSigned = std::is_signed<OfType>::value,
|
|
||||||
bool TSigned = std::is_signed<T>::value>
|
|
||||||
struct value_in_range_of_impl2;
|
struct value_in_range_of_impl2;
|
||||||
|
|
||||||
template<typename OfType, typename T>
|
template<typename OfType, typename T>
|
||||||
@@ -705,12 +697,13 @@ struct value_in_range_of_impl2<OfType, T, true, true>
|
|||||||
static constexpr bool test(T val)
|
static constexpr bool test(T val)
|
||||||
{
|
{
|
||||||
using CommonType = typename std::common_type<OfType, T>::type;
|
using CommonType = typename std::common_type<OfType, T>::type;
|
||||||
return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
|
return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)()) &&
|
||||||
&& static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
|
static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename OfType, typename T,
|
template<typename OfType,
|
||||||
|
typename T,
|
||||||
bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
|
bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
|
||||||
typename = detail::enable_if_t<all_integral<OfType, T>::value>>
|
typename = detail::enable_if_t<all_integral<OfType, T>::value>>
|
||||||
struct value_in_range_of_impl1;
|
struct value_in_range_of_impl1;
|
||||||
@@ -756,16 +749,15 @@ inline constexpr bool is_c_string()
|
|||||||
using TUnCVExt = typename std::remove_cv<TUnExt>::type;
|
using TUnCVExt = typename std::remove_cv<TUnExt>::type;
|
||||||
using TUnPtr = typename std::remove_pointer<T>::type;
|
using TUnPtr = typename std::remove_pointer<T>::type;
|
||||||
using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
|
using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
|
||||||
return
|
return (std::is_array<T>::value && std::is_same<TUnCVExt, char>::value) || (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
|
||||||
(std::is_array<T>::value && std::is_same<TUnCVExt, char>::value)
|
|
||||||
|| (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
|
||||||
// checks whether T is a [cv] char */[cv] char[] C string
|
// checks whether T is a [cv] char */[cv] char[] C string
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
|
struct is_c_string : bool_constant<impl::is_c_string<T>()>
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using is_c_string_uncvref = is_c_string<uncvref_t<T>>;
|
using is_c_string_uncvref = is_c_string<uncvref_t<T>>;
|
||||||
@@ -787,7 +779,8 @@ inline constexpr bool is_transparent()
|
|||||||
|
|
||||||
// checks whether T has a member named is_transparent
|
// checks whether T has a member named is_transparent
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
|
struct is_transparent : bool_constant<impl::is_transparent<T>()>
|
||||||
|
{};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,13 @@ NLOHMANN_JSON_NAMESPACE_BEGIN
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename ...Ts> struct make_void
|
template<typename... Ts>
|
||||||
|
struct make_void
|
||||||
{
|
{
|
||||||
using type = void;
|
using type = void;
|
||||||
};
|
};
|
||||||
template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
|
template<typename... Ts>
|
||||||
|
using void_t = typename make_void<Ts...>::type;
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
|
|
||||||
#include <algorithm> // reverse
|
#include <algorithm> // reverse
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
#include <map> // map
|
|
||||||
#include <cmath> // isnan, isinf
|
#include <cmath> // isnan, isinf
|
||||||
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
|
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
|
||||||
#include <cstring> // memcpy
|
#include <cstring> // memcpy
|
||||||
#include <limits> // numeric_limits
|
#include <limits> // numeric_limits
|
||||||
|
#include <map> // map
|
||||||
#include <string> // string
|
#include <string> // string
|
||||||
#include <utility> // move
|
#include <utility> // move
|
||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
@@ -48,7 +48,8 @@ class binary_writer
|
|||||||
|
|
||||||
@param[in] adapter output adapter to write to
|
@param[in] adapter output adapter to write to
|
||||||
*/
|
*/
|
||||||
explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
|
explicit binary_writer(output_adapter_t<CharType> adapter)
|
||||||
|
: oa(std::move(adapter))
|
||||||
{
|
{
|
||||||
JSON_ASSERT(oa);
|
JSON_ASSERT(oa);
|
||||||
}
|
}
|
||||||
@@ -98,9 +99,7 @@ class binary_writer
|
|||||||
|
|
||||||
case value_t::boolean:
|
case value_t::boolean:
|
||||||
{
|
{
|
||||||
oa->write_character(j.m_data.m_value.boolean
|
oa->write_character(j.m_data.m_value.boolean ? to_char_type(0xF5) : to_char_type(0xF4));
|
||||||
? to_char_type(0xF5)
|
|
||||||
: to_char_type(0xF4));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,9 +252,7 @@ class binary_writer
|
|||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
|
||||||
// step 2: write the string
|
// step 2: write the string
|
||||||
oa->write_characters(
|
oa->write_characters(reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()), j.m_data.m_value.string->size());
|
||||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
|
||||||
j.m_data.m_value.string->size());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,9 +351,7 @@ class binary_writer
|
|||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
|
||||||
// step 2: write each element
|
// step 2: write each element
|
||||||
oa->write_characters(
|
oa->write_characters(reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()), N);
|
||||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
|
||||||
N);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -422,9 +417,7 @@ class binary_writer
|
|||||||
|
|
||||||
case value_t::boolean: // true and false
|
case value_t::boolean: // true and false
|
||||||
{
|
{
|
||||||
oa->write_character(j.m_data.m_value.boolean
|
oa->write_character(j.m_data.m_value.boolean ? to_char_type(0xC3) : to_char_type(0xC2));
|
||||||
? to_char_type(0xC3)
|
|
||||||
: to_char_type(0xC2));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,9 +566,7 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// step 2: write the string
|
// step 2: write the string
|
||||||
oa->write_characters(
|
oa->write_characters(reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()), j.m_data.m_value.string->size());
|
||||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
|
||||||
j.m_data.m_value.string->size());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -645,7 +636,6 @@ class binary_writer
|
|||||||
fixed = false;
|
fixed = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -661,8 +651,7 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||||
{
|
{
|
||||||
const std::uint8_t output_type = use_ext
|
const std::uint8_t output_type = use_ext ? 0xC8 // ext 16
|
||||||
? 0xC8 // ext 16
|
|
||||||
: 0xC5; // bin 16
|
: 0xC5; // bin 16
|
||||||
|
|
||||||
oa->write_character(to_char_type(output_type));
|
oa->write_character(to_char_type(output_type));
|
||||||
@@ -670,8 +659,7 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||||
{
|
{
|
||||||
const std::uint8_t output_type = use_ext
|
const std::uint8_t output_type = use_ext ? 0xC9 // ext 32
|
||||||
? 0xC9 // ext 32
|
|
||||||
: 0xC6; // bin 32
|
: 0xC6; // bin 32
|
||||||
|
|
||||||
oa->write_character(to_char_type(output_type));
|
oa->write_character(to_char_type(output_type));
|
||||||
@@ -685,9 +673,7 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// step 2: write the byte string
|
// step 2: write the byte string
|
||||||
oa->write_characters(
|
oa->write_characters(reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()), N);
|
||||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
|
||||||
N);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -736,9 +722,7 @@ class binary_writer
|
|||||||
@param[in] add_prefix whether prefixes need to be used for this value
|
@param[in] add_prefix whether prefixes need to be used for this value
|
||||||
@param[in] use_bjdata whether write in BJData format, default is false
|
@param[in] use_bjdata whether write in BJData format, default is false
|
||||||
*/
|
*/
|
||||||
void write_ubjson(const BasicJsonType& j, const bool use_count,
|
void write_ubjson(const BasicJsonType& j, const bool use_count, const bool use_type, const bool add_prefix = true, const bool use_bjdata = false)
|
||||||
const bool use_type, const bool add_prefix = true,
|
|
||||||
const bool use_bjdata = false)
|
|
||||||
{
|
{
|
||||||
switch (j.type())
|
switch (j.type())
|
||||||
{
|
{
|
||||||
@@ -755,9 +739,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
oa->write_character(j.m_data.m_value.boolean
|
oa->write_character(j.m_data.m_value.boolean ? to_char_type('T') : to_char_type('F'));
|
||||||
? to_char_type('T')
|
|
||||||
: to_char_type('F'));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -787,9 +769,7 @@ class binary_writer
|
|||||||
oa->write_character(to_char_type('S'));
|
oa->write_character(to_char_type('S'));
|
||||||
}
|
}
|
||||||
write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
|
write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
|
||||||
oa->write_characters(
|
oa->write_characters(reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()), j.m_data.m_value.string->size());
|
||||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
|
||||||
j.m_data.m_value.string->size());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,9 +785,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
JSON_ASSERT(use_count);
|
JSON_ASSERT(use_count);
|
||||||
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
|
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
|
||||||
const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
|
const bool same_prefix = std::all_of(j.begin() + 1, j.end(), [this, first_prefix, use_bjdata](const BasicJsonType& v) {
|
||||||
[this, first_prefix, use_bjdata](const BasicJsonType & v)
|
|
||||||
{
|
|
||||||
return ubjson_prefix(v, use_bjdata) == first_prefix;
|
return ubjson_prefix(v, use_bjdata) == first_prefix;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -862,9 +840,7 @@ class binary_writer
|
|||||||
|
|
||||||
if (use_type)
|
if (use_type)
|
||||||
{
|
{
|
||||||
oa->write_characters(
|
oa->write_characters(reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()), j.m_data.m_value.binary->size());
|
||||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
|
||||||
j.m_data.m_value.binary->size());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -885,9 +861,13 @@ class binary_writer
|
|||||||
|
|
||||||
case value_t::object:
|
case value_t::object:
|
||||||
{
|
{
|
||||||
if (use_bjdata && j.m_data.m_value.object->size() == 3 && j.m_data.m_value.object->find("_ArrayType_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArraySize_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArrayData_") != j.m_data.m_value.object->end())
|
if (use_bjdata && j.m_data.m_value.object->size() == 3 && j.m_data.m_value.object->find("_ArrayType_") != j.m_data.m_value.object->end() &&
|
||||||
|
j.m_data.m_value.object->find("_ArraySize_") != j.m_data.m_value.object->end() &&
|
||||||
|
j.m_data.m_value.object->find("_ArrayData_") != j.m_data.m_value.object->end())
|
||||||
{
|
{
|
||||||
if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
|
if (!write_bjdata_ndarray(*j.m_data.m_value.object,
|
||||||
|
use_count,
|
||||||
|
use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -903,9 +883,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
JSON_ASSERT(use_count);
|
JSON_ASSERT(use_count);
|
||||||
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
|
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
|
||||||
const bool same_prefix = std::all_of(j.begin(), j.end(),
|
const bool same_prefix = std::all_of(j.begin(), j.end(), [this, first_prefix, use_bjdata](const BasicJsonType& v) {
|
||||||
[this, first_prefix, use_bjdata](const BasicJsonType & v)
|
|
||||||
{
|
|
||||||
return ubjson_prefix(v, use_bjdata) == first_prefix;
|
return ubjson_prefix(v, use_bjdata) == first_prefix;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -928,9 +906,7 @@ class binary_writer
|
|||||||
for (const auto& el : *j.m_data.m_value.object)
|
for (const auto& el : *j.m_data.m_value.object)
|
||||||
{
|
{
|
||||||
write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
|
write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
|
||||||
oa->write_characters(
|
oa->write_characters(reinterpret_cast<const CharType*>(el.first.c_str()), el.first.size());
|
||||||
reinterpret_cast<const CharType*>(el.first.c_str()),
|
|
||||||
el.first.size());
|
|
||||||
write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
|
write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -972,20 +948,16 @@ class binary_writer
|
|||||||
/*!
|
/*!
|
||||||
@brief Writes the given @a element_type and @a name to the output adapter
|
@brief Writes the given @a element_type and @a name to the output adapter
|
||||||
*/
|
*/
|
||||||
void write_bson_entry_header(const string_t& name,
|
void write_bson_entry_header(const string_t& name, const std::uint8_t element_type)
|
||||||
const std::uint8_t element_type)
|
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type(element_type)); // boolean
|
oa->write_character(to_char_type(element_type)); // boolean
|
||||||
oa->write_characters(
|
oa->write_characters(reinterpret_cast<const CharType*>(name.c_str()), name.size() + 1u);
|
||||||
reinterpret_cast<const CharType*>(name.c_str()),
|
|
||||||
name.size() + 1u);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief Writes a BSON element with key @a name and boolean value @a value
|
@brief Writes a BSON element with key @a name and boolean value @a value
|
||||||
*/
|
*/
|
||||||
void write_bson_boolean(const string_t& name,
|
void write_bson_boolean(const string_t& name, const bool value)
|
||||||
const bool value)
|
|
||||||
{
|
{
|
||||||
write_bson_entry_header(name, 0x08);
|
write_bson_entry_header(name, 0x08);
|
||||||
oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
|
oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
|
||||||
@@ -994,8 +966,7 @@ class binary_writer
|
|||||||
/*!
|
/*!
|
||||||
@brief Writes a BSON element with key @a name and double value @a value
|
@brief Writes a BSON element with key @a name and double value @a value
|
||||||
*/
|
*/
|
||||||
void write_bson_double(const string_t& name,
|
void write_bson_double(const string_t& name, const double value)
|
||||||
const double value)
|
|
||||||
{
|
{
|
||||||
write_bson_entry_header(name, 0x01);
|
write_bson_entry_header(name, 0x01);
|
||||||
write_number<double>(value, true);
|
write_number<double>(value, true);
|
||||||
@@ -1012,15 +983,12 @@ class binary_writer
|
|||||||
/*!
|
/*!
|
||||||
@brief Writes a BSON element with key @a name and string value @a value
|
@brief Writes a BSON element with key @a name and string value @a value
|
||||||
*/
|
*/
|
||||||
void write_bson_string(const string_t& name,
|
void write_bson_string(const string_t& name, const string_t& value)
|
||||||
const string_t& value)
|
|
||||||
{
|
{
|
||||||
write_bson_entry_header(name, 0x02);
|
write_bson_entry_header(name, 0x02);
|
||||||
|
|
||||||
write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
|
write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
|
||||||
oa->write_characters(
|
oa->write_characters(reinterpret_cast<const CharType*>(value.c_str()), value.size() + 1);
|
||||||
reinterpret_cast<const CharType*>(value.c_str()),
|
|
||||||
value.size() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -1036,16 +1004,14 @@ class binary_writer
|
|||||||
*/
|
*/
|
||||||
static std::size_t calc_bson_integer_size(const std::int64_t value)
|
static std::size_t calc_bson_integer_size(const std::int64_t value)
|
||||||
{
|
{
|
||||||
return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
|
return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)() ? sizeof(std::int32_t)
|
||||||
? sizeof(std::int32_t)
|
|
||||||
: sizeof(std::int64_t);
|
: sizeof(std::int64_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief Writes a BSON element with key @a name and integer @a value
|
@brief Writes a BSON element with key @a name and integer @a value
|
||||||
*/
|
*/
|
||||||
void write_bson_integer(const string_t& name,
|
void write_bson_integer(const string_t& name, const std::int64_t value)
|
||||||
const std::int64_t value)
|
|
||||||
{
|
{
|
||||||
if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
|
if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
|
||||||
{
|
{
|
||||||
@@ -1064,16 +1030,13 @@ class binary_writer
|
|||||||
*/
|
*/
|
||||||
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
|
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
|
||||||
{
|
{
|
||||||
return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
|
return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)())) ? sizeof(std::int32_t) : sizeof(std::int64_t);
|
||||||
? sizeof(std::int32_t)
|
|
||||||
: sizeof(std::int64_t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief Writes a BSON element with key @a name and unsigned @a value
|
@brief Writes a BSON element with key @a name and unsigned @a value
|
||||||
*/
|
*/
|
||||||
void write_bson_unsigned(const string_t& name,
|
void write_bson_unsigned(const string_t& name, const BasicJsonType& j)
|
||||||
const BasicJsonType& j)
|
|
||||||
{
|
{
|
||||||
if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
|
if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
|
||||||
{
|
{
|
||||||
@@ -1087,15 +1050,17 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
|
JSON_THROW(out_of_range::create(
|
||||||
|
407,
|
||||||
|
concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"),
|
||||||
|
&j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief Writes a BSON element with key @a name and object @a value
|
@brief Writes a BSON element with key @a name and object @a value
|
||||||
*/
|
*/
|
||||||
void write_bson_object_entry(const string_t& name,
|
void write_bson_object_entry(const string_t& name, const typename BasicJsonType::object_t& value)
|
||||||
const typename BasicJsonType::object_t& value)
|
|
||||||
{
|
{
|
||||||
write_bson_entry_header(name, 0x03); // object
|
write_bson_entry_header(name, 0x03); // object
|
||||||
write_bson_object(value);
|
write_bson_object(value);
|
||||||
@@ -1108,8 +1073,10 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
std::size_t array_index = 0ul;
|
std::size_t array_index = 0ul;
|
||||||
|
|
||||||
const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
|
const std::size_t embedded_document_size = std::accumulate(std::begin(value),
|
||||||
{
|
std::end(value),
|
||||||
|
static_cast<std::size_t>(0),
|
||||||
|
[&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type& el) {
|
||||||
return result + calc_bson_element_size(std::to_string(array_index++), el);
|
return result + calc_bson_element_size(std::to_string(array_index++), el);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1127,8 +1094,7 @@ class binary_writer
|
|||||||
/*!
|
/*!
|
||||||
@brief Writes a BSON element with key @a name and array @a value
|
@brief Writes a BSON element with key @a name and array @a value
|
||||||
*/
|
*/
|
||||||
void write_bson_array(const string_t& name,
|
void write_bson_array(const string_t& name, const typename BasicJsonType::array_t& value)
|
||||||
const typename BasicJsonType::array_t& value)
|
|
||||||
{
|
{
|
||||||
write_bson_entry_header(name, 0x04); // array
|
write_bson_entry_header(name, 0x04); // array
|
||||||
write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
|
write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
|
||||||
@@ -1146,8 +1112,7 @@ class binary_writer
|
|||||||
/*!
|
/*!
|
||||||
@brief Writes a BSON element with key @a name and binary value @a value
|
@brief Writes a BSON element with key @a name and binary value @a value
|
||||||
*/
|
*/
|
||||||
void write_bson_binary(const string_t& name,
|
void write_bson_binary(const string_t& name, const binary_t& value)
|
||||||
const binary_t& value)
|
|
||||||
{
|
{
|
||||||
write_bson_entry_header(name, 0x05);
|
write_bson_entry_header(name, 0x05);
|
||||||
|
|
||||||
@@ -1161,8 +1126,7 @@ class binary_writer
|
|||||||
@brief Calculates the size necessary to serialize the JSON value @a j with its @a name
|
@brief Calculates the size necessary to serialize the JSON value @a j with its @a name
|
||||||
@return The calculated size for the BSON document entry for @a j with the given @a name.
|
@return The calculated size for the BSON document entry for @a j with the given @a name.
|
||||||
*/
|
*/
|
||||||
static std::size_t calc_bson_element_size(const string_t& name,
|
static std::size_t calc_bson_element_size(const string_t& name, const BasicJsonType& j)
|
||||||
const BasicJsonType& j)
|
|
||||||
{
|
{
|
||||||
const auto header_size = calc_bson_entry_header_size(name, j);
|
const auto header_size = calc_bson_entry_header_size(name, j);
|
||||||
switch (j.type())
|
switch (j.type())
|
||||||
@@ -1209,8 +1173,7 @@ class binary_writer
|
|||||||
@param name The name to associate with the JSON entity @a j within the
|
@param name The name to associate with the JSON entity @a j within the
|
||||||
current BSON document
|
current BSON document
|
||||||
*/
|
*/
|
||||||
void write_bson_element(const string_t& name,
|
void write_bson_element(const string_t& name, const BasicJsonType& j)
|
||||||
const BasicJsonType& j)
|
|
||||||
{
|
{
|
||||||
switch (j.type())
|
switch (j.type())
|
||||||
{
|
{
|
||||||
@@ -1258,9 +1221,8 @@ class binary_writer
|
|||||||
*/
|
*/
|
||||||
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
|
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
|
||||||
{
|
{
|
||||||
const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
|
const std::size_t document_size =
|
||||||
[](size_t result, const typename BasicJsonType::object_t::value_type & el)
|
std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0), [](size_t result, const typename BasicJsonType::object_t::value_type& el) {
|
||||||
{
|
|
||||||
return result += calc_bson_element_size(el.first, el.second);
|
return result += calc_bson_element_size(el.first, el.second);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1316,11 +1278,8 @@ class binary_writer
|
|||||||
////////////
|
////////////
|
||||||
|
|
||||||
// UBJSON: write number (floating point)
|
// UBJSON: write number (floating point)
|
||||||
template<typename NumberType, typename std::enable_if<
|
template<typename NumberType, typename std::enable_if<std::is_floating_point<NumberType>::value, int>::type = 0>
|
||||||
std::is_floating_point<NumberType>::value, int>::type = 0>
|
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix, const bool use_bjdata)
|
||||||
void write_number_with_ubjson_prefix(const NumberType n,
|
|
||||||
const bool add_prefix,
|
|
||||||
const bool use_bjdata)
|
|
||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
@@ -1330,11 +1289,8 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UBJSON: write number (unsigned integer)
|
// UBJSON: write number (unsigned integer)
|
||||||
template<typename NumberType, typename std::enable_if<
|
template<typename NumberType, typename std::enable_if<std::is_unsigned<NumberType>::value, int>::type = 0>
|
||||||
std::is_unsigned<NumberType>::value, int>::type = 0>
|
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix, const bool use_bjdata)
|
||||||
void write_number_with_ubjson_prefix(const NumberType n,
|
|
||||||
const bool add_prefix,
|
|
||||||
const bool use_bjdata)
|
|
||||||
{
|
{
|
||||||
if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
|
if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
|
||||||
{
|
{
|
||||||
@@ -1417,12 +1373,8 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UBJSON: write number (signed integer)
|
// UBJSON: write number (signed integer)
|
||||||
template < typename NumberType, typename std::enable_if <
|
template<typename NumberType, typename std::enable_if<std::is_signed<NumberType>::value && !std::is_floating_point<NumberType>::value, int>::type = 0>
|
||||||
std::is_signed<NumberType>::value&&
|
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix, const bool use_bjdata)
|
||||||
!std::is_floating_point<NumberType>::value, int >::type = 0 >
|
|
||||||
void write_number_with_ubjson_prefix(const NumberType n,
|
|
||||||
const bool add_prefix,
|
|
||||||
const bool use_bjdata)
|
|
||||||
{
|
{
|
||||||
if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
|
if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
|
||||||
{
|
{
|
||||||
@@ -1432,7 +1384,8 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
write_number(static_cast<std::int8_t>(n), use_bjdata);
|
write_number(static_cast<std::int8_t>(n), use_bjdata);
|
||||||
}
|
}
|
||||||
else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
|
else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n &&
|
||||||
|
n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
|
||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
@@ -1448,7 +1401,8 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
write_number(static_cast<std::int16_t>(n), use_bjdata);
|
write_number(static_cast<std::int16_t>(n), use_bjdata);
|
||||||
}
|
}
|
||||||
else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
|
else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n &&
|
||||||
|
n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
|
||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
@@ -1464,7 +1418,8 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
write_number(static_cast<std::int32_t>(n), use_bjdata);
|
write_number(static_cast<std::int32_t>(n), use_bjdata);
|
||||||
}
|
}
|
||||||
else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
|
else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n &&
|
||||||
|
n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
|
||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
@@ -1513,31 +1468,38 @@ class binary_writer
|
|||||||
|
|
||||||
case value_t::number_integer:
|
case value_t::number_integer:
|
||||||
{
|
{
|
||||||
if ((std::numeric_limits<std::int8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
|
if ((std::numeric_limits<std::int8_t>::min)() <= j.m_data.m_value.number_integer &&
|
||||||
|
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
|
||||||
{
|
{
|
||||||
return 'i';
|
return 'i';
|
||||||
}
|
}
|
||||||
if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
|
if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_data.m_value.number_integer &&
|
||||||
|
j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
|
||||||
{
|
{
|
||||||
return 'U';
|
return 'U';
|
||||||
}
|
}
|
||||||
if ((std::numeric_limits<std::int16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
|
if ((std::numeric_limits<std::int16_t>::min)() <= j.m_data.m_value.number_integer &&
|
||||||
|
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
|
||||||
{
|
{
|
||||||
return 'I';
|
return 'I';
|
||||||
}
|
}
|
||||||
if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
|
if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_data.m_value.number_integer &&
|
||||||
|
j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
|
||||||
{
|
{
|
||||||
return 'u';
|
return 'u';
|
||||||
}
|
}
|
||||||
if ((std::numeric_limits<std::int32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
|
if ((std::numeric_limits<std::int32_t>::min)() <= j.m_data.m_value.number_integer &&
|
||||||
|
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
|
||||||
{
|
{
|
||||||
return 'l';
|
return 'l';
|
||||||
}
|
}
|
||||||
if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
|
if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_data.m_value.number_integer &&
|
||||||
|
j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
|
||||||
{
|
{
|
||||||
return 'm';
|
return 'm';
|
||||||
}
|
}
|
||||||
if ((std::numeric_limits<std::int64_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
|
if ((std::numeric_limits<std::int64_t>::min)() <= j.m_data.m_value.number_integer &&
|
||||||
|
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
|
||||||
{
|
{
|
||||||
return 'L';
|
return 'L';
|
||||||
}
|
}
|
||||||
@@ -1617,9 +1579,8 @@ class binary_writer
|
|||||||
*/
|
*/
|
||||||
bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
|
bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
|
||||||
{
|
{
|
||||||
std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
|
std::map<string_t, CharType> bjdtype = { { "uint8", 'U' }, { "int8", 'i' }, { "uint16", 'u' }, { "int16", 'I' }, { "uint32", 'm' }, { "int32", 'l' },
|
||||||
{"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
|
{ "uint64", 'M' }, { "int64", 'L' }, { "single", 'd' }, { "double", 'D' }, { "char", 'C' } };
|
||||||
};
|
|
||||||
|
|
||||||
string_t key = "_ArrayType_";
|
string_t key = "_ArrayType_";
|
||||||
auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
|
auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
|
||||||
@@ -1768,16 +1729,13 @@ class binary_writer
|
|||||||
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
|
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
|
||||||
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
|
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
|
||||||
{
|
{
|
||||||
oa->write_character(format == detail::input_format_t::cbor
|
oa->write_character(format == detail::input_format_t::cbor ? get_cbor_float_prefix(static_cast<float>(n))
|
||||||
? get_cbor_float_prefix(static_cast<float>(n))
|
|
||||||
: get_msgpack_float_prefix(static_cast<float>(n)));
|
: get_msgpack_float_prefix(static_cast<float>(n)));
|
||||||
write_number(static_cast<float>(n));
|
write_number(static_cast<float>(n));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
oa->write_character(format == detail::input_format_t::cbor
|
oa->write_character(format == detail::input_format_t::cbor ? get_cbor_float_prefix(n) : get_msgpack_float_prefix(n));
|
||||||
? get_cbor_float_prefix(n)
|
|
||||||
: get_msgpack_float_prefix(n));
|
|
||||||
write_number(n);
|
write_number(n);
|
||||||
}
|
}
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@@ -1790,15 +1748,13 @@ class binary_writer
|
|||||||
// between uint8_t and CharType. In case CharType is not unsigned,
|
// between uint8_t and CharType. In case CharType is not unsigned,
|
||||||
// such a conversion is required to allow values greater than 128.
|
// such a conversion is required to allow values greater than 128.
|
||||||
// See <https://github.com/nlohmann/json/issues/1286> for a discussion.
|
// See <https://github.com/nlohmann/json/issues/1286> for a discussion.
|
||||||
template < typename C = CharType,
|
template<typename C = CharType, enable_if_t<std::is_signed<C>::value && std::is_signed<char>::value>* = nullptr>
|
||||||
enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
|
|
||||||
static constexpr CharType to_char_type(std::uint8_t x) noexcept
|
static constexpr CharType to_char_type(std::uint8_t x) noexcept
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<char*>(&x);
|
return *reinterpret_cast<char*>(&x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename C = CharType,
|
template<typename C = CharType, enable_if_t<std::is_signed<C>::value && std::is_unsigned<char>::value>* = nullptr>
|
||||||
enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
|
|
||||||
static CharType to_char_type(std::uint8_t x) noexcept
|
static CharType to_char_type(std::uint8_t x) noexcept
|
||||||
{
|
{
|
||||||
static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
|
static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
|
||||||
@@ -1808,19 +1764,16 @@ class binary_writer
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename C = CharType,
|
template<typename C = CharType, enable_if_t<std::is_unsigned<C>::value>* = nullptr>
|
||||||
enable_if_t<std::is_unsigned<C>::value>* = nullptr>
|
|
||||||
static constexpr CharType to_char_type(std::uint8_t x) noexcept
|
static constexpr CharType to_char_type(std::uint8_t x) noexcept
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename InputCharType, typename C = CharType,
|
template<typename InputCharType,
|
||||||
enable_if_t <
|
typename C = CharType,
|
||||||
std::is_signed<C>::value &&
|
enable_if_t<std::is_signed<C>::value && std::is_signed<char>::value && std::is_same<char, typename std::remove_cv<InputCharType>::type>::value>* =
|
||||||
std::is_signed<char>::value &&
|
nullptr>
|
||||||
std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
|
|
||||||
> * = nullptr >
|
|
||||||
static constexpr CharType to_char_type(InputCharType x) noexcept
|
static constexpr CharType to_char_type(InputCharType x) noexcept
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ namespace detail
|
|||||||
{
|
{
|
||||||
|
|
||||||
/// abstract output adapter interface
|
/// abstract output adapter interface
|
||||||
template<typename CharType> struct output_adapter_protocol
|
template<typename CharType>
|
||||||
|
struct output_adapter_protocol
|
||||||
{
|
{
|
||||||
virtual void write_character(CharType c) = 0;
|
virtual void write_character(CharType c) = 0;
|
||||||
virtual void write_characters(const CharType* s, std::size_t length) = 0;
|
virtual void write_characters(const CharType* s, std::size_t length) = 0;
|
||||||
@@ -124,15 +125,18 @@ class output_adapter
|
|||||||
public:
|
public:
|
||||||
template<typename AllocatorType = std::allocator<CharType>>
|
template<typename AllocatorType = std::allocator<CharType>>
|
||||||
output_adapter(std::vector<CharType, AllocatorType>& vec)
|
output_adapter(std::vector<CharType, AllocatorType>& vec)
|
||||||
: oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
|
: oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec))
|
||||||
|
{}
|
||||||
|
|
||||||
#ifndef JSON_NO_IO
|
#ifndef JSON_NO_IO
|
||||||
output_adapter(std::basic_ostream<CharType>& s)
|
output_adapter(std::basic_ostream<CharType>& s)
|
||||||
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
|
: oa(std::make_shared<output_stream_adapter<CharType>>(s))
|
||||||
|
{}
|
||||||
#endif // JSON_NO_IO
|
#endif // JSON_NO_IO
|
||||||
|
|
||||||
output_adapter(StringType& s)
|
output_adapter(StringType& s)
|
||||||
: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
|
: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s))
|
||||||
|
{}
|
||||||
|
|
||||||
operator output_adapter_t<CharType>()
|
operator output_adapter_t<CharType>()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
#include <cstddef> // size_t, ptrdiff_t
|
#include <cstddef> // size_t, ptrdiff_t
|
||||||
#include <cstdint> // uint8_t
|
#include <cstdint> // uint8_t
|
||||||
#include <cstdio> // snprintf
|
#include <cstdio> // snprintf
|
||||||
|
#include <iomanip> // setfill, setw
|
||||||
#include <limits> // numeric_limits
|
#include <limits> // numeric_limits
|
||||||
#include <string> // string, char_traits
|
#include <string> // string, char_traits
|
||||||
#include <iomanip> // setfill, setw
|
|
||||||
#include <type_traits> // is_same
|
#include <type_traits> // is_same
|
||||||
#include <utility> // move
|
#include <utility> // move
|
||||||
|
|
||||||
@@ -64,8 +64,7 @@ class serializer
|
|||||||
@param[in] ichar indentation character to use
|
@param[in] ichar indentation character to use
|
||||||
@param[in] error_handler_ how to react on decoding errors
|
@param[in] error_handler_ how to react on decoding errors
|
||||||
*/
|
*/
|
||||||
serializer(output_adapter_t<char> s, const char ichar,
|
serializer(output_adapter_t<char> s, const char ichar, error_handler_t error_handler_ = error_handler_t::strict)
|
||||||
error_handler_t error_handler_ = error_handler_t::strict)
|
|
||||||
: o(std::move(s))
|
: o(std::move(s))
|
||||||
, loc(std::localeconv())
|
, loc(std::localeconv())
|
||||||
, thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->thousands_sep)))
|
, thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->thousands_sep)))
|
||||||
@@ -104,11 +103,7 @@ class serializer
|
|||||||
@param[in] indent_step the indent level
|
@param[in] indent_step the indent level
|
||||||
@param[in] current_indent the current indent level (only used internally)
|
@param[in] current_indent the current indent level (only used internally)
|
||||||
*/
|
*/
|
||||||
void dump(const BasicJsonType& val,
|
void dump(const BasicJsonType& val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent = 0)
|
||||||
const bool pretty_print,
|
|
||||||
const bool ensure_ascii,
|
|
||||||
const unsigned int indent_step,
|
|
||||||
const unsigned int current_indent = 0)
|
|
||||||
{
|
{
|
||||||
switch (val.m_data.m_type)
|
switch (val.m_data.m_type)
|
||||||
{
|
{
|
||||||
@@ -205,8 +200,7 @@ class serializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// first n-1 elements
|
// first n-1 elements
|
||||||
for (auto i = val.m_data.m_value.array->cbegin();
|
for (auto i = val.m_data.m_value.array->cbegin(); i != val.m_data.m_value.array->cend() - 1; ++i)
|
||||||
i != val.m_data.m_value.array->cend() - 1; ++i)
|
|
||||||
{
|
{
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o->write_characters(indent_string.c_str(), new_indent);
|
||||||
dump(*i, true, ensure_ascii, indent_step, new_indent);
|
dump(*i, true, ensure_ascii, indent_step, new_indent);
|
||||||
@@ -227,8 +221,7 @@ class serializer
|
|||||||
o->write_character('[');
|
o->write_character('[');
|
||||||
|
|
||||||
// first n-1 elements
|
// first n-1 elements
|
||||||
for (auto i = val.m_data.m_value.array->cbegin();
|
for (auto i = val.m_data.m_value.array->cbegin(); i != val.m_data.m_value.array->cend() - 1; ++i)
|
||||||
i != val.m_data.m_value.array->cend() - 1; ++i)
|
|
||||||
{
|
{
|
||||||
dump(*i, false, ensure_ascii, indent_step, current_indent);
|
dump(*i, false, ensure_ascii, indent_step, current_indent);
|
||||||
o->write_character(',');
|
o->write_character(',');
|
||||||
@@ -271,8 +264,7 @@ class serializer
|
|||||||
|
|
||||||
if (!val.m_data.m_value.binary->empty())
|
if (!val.m_data.m_value.binary->empty())
|
||||||
{
|
{
|
||||||
for (auto i = val.m_data.m_value.binary->cbegin();
|
for (auto i = val.m_data.m_value.binary->cbegin(); i != val.m_data.m_value.binary->cend() - 1; ++i)
|
||||||
i != val.m_data.m_value.binary->cend() - 1; ++i)
|
|
||||||
{
|
{
|
||||||
dump_integer(*i);
|
dump_integer(*i);
|
||||||
o->write_characters(", ", 2);
|
o->write_characters(", ", 2);
|
||||||
@@ -302,8 +294,7 @@ class serializer
|
|||||||
|
|
||||||
if (!val.m_data.m_value.binary->empty())
|
if (!val.m_data.m_value.binary->empty())
|
||||||
{
|
{
|
||||||
for (auto i = val.m_data.m_value.binary->cbegin();
|
for (auto i = val.m_data.m_value.binary->cbegin(); i != val.m_data.m_value.binary->cend() - 1; ++i)
|
||||||
i != val.m_data.m_value.binary->cend() - 1; ++i)
|
|
||||||
{
|
{
|
||||||
dump_integer(*i);
|
dump_integer(*i);
|
||||||
o->write_character(',');
|
o->write_character(',');
|
||||||
@@ -466,14 +457,15 @@ class serializer
|
|||||||
if (codepoint <= 0xFFFF)
|
if (codepoint <= 0xFFFF)
|
||||||
{
|
{
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
|
static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x", static_cast<std::uint16_t>(codepoint)));
|
||||||
static_cast<std::uint16_t>(codepoint)));
|
|
||||||
bytes += 6;
|
bytes += 6;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
|
static_cast<void>((std::snprintf)(string_buffer.data() + bytes,
|
||||||
|
13,
|
||||||
|
"\\u%04x\\u%04x",
|
||||||
static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
|
static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
|
||||||
static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
|
static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
|
||||||
bytes += 12;
|
bytes += 12;
|
||||||
@@ -510,7 +502,8 @@ class serializer
|
|||||||
{
|
{
|
||||||
case error_handler_t::strict:
|
case error_handler_t::strict:
|
||||||
{
|
{
|
||||||
JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
|
JSON_THROW(
|
||||||
|
type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
case error_handler_t::ignore:
|
case error_handler_t::ignore:
|
||||||
@@ -602,7 +595,8 @@ class serializer
|
|||||||
{
|
{
|
||||||
case error_handler_t::strict:
|
case error_handler_t::strict:
|
||||||
{
|
{
|
||||||
JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
|
JSON_THROW(
|
||||||
|
type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
case error_handler_t::ignore:
|
case error_handler_t::ignore:
|
||||||
@@ -705,29 +699,27 @@ class serializer
|
|||||||
@param[in] x integer number (signed or unsigned) to dump
|
@param[in] x integer number (signed or unsigned) to dump
|
||||||
@tparam NumberType either @a number_integer_t or @a number_unsigned_t
|
@tparam NumberType either @a number_integer_t or @a number_unsigned_t
|
||||||
*/
|
*/
|
||||||
template < typename NumberType, detail::enable_if_t <
|
template<typename NumberType,
|
||||||
std::is_integral<NumberType>::value ||
|
detail::enable_if_t<std::is_integral<NumberType>::value || std::is_same<NumberType, number_unsigned_t>::value ||
|
||||||
std::is_same<NumberType, number_unsigned_t>::value ||
|
std::is_same<NumberType, number_integer_t>::value || std::is_same<NumberType, binary_char_t>::value,
|
||||||
std::is_same<NumberType, number_integer_t>::value ||
|
|
||||||
std::is_same<NumberType, binary_char_t>::value,
|
|
||||||
int> = 0>
|
int> = 0>
|
||||||
void dump_integer(NumberType x)
|
void dump_integer(NumberType x)
|
||||||
{
|
{
|
||||||
static constexpr std::array<std::array<char, 2>, 100> digits_to_99
|
static constexpr std::array<std::array<char, 2>, 100> digits_to_99{ {
|
||||||
{
|
{ { '0', '0' } }, { { '0', '1' } }, { { '0', '2' } }, { { '0', '3' } }, { { '0', '4' } }, { { '0', '5' } }, { { '0', '6' } }, { { '0', '7' } },
|
||||||
{
|
{ { '0', '8' } }, { { '0', '9' } }, { { '1', '0' } }, { { '1', '1' } }, { { '1', '2' } }, { { '1', '3' } }, { { '1', '4' } }, { { '1', '5' } },
|
||||||
{{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
|
{ { '1', '6' } }, { { '1', '7' } }, { { '1', '8' } }, { { '1', '9' } }, { { '2', '0' } }, { { '2', '1' } }, { { '2', '2' } }, { { '2', '3' } },
|
||||||
{{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
|
{ { '2', '4' } }, { { '2', '5' } }, { { '2', '6' } }, { { '2', '7' } }, { { '2', '8' } }, { { '2', '9' } }, { { '3', '0' } }, { { '3', '1' } },
|
||||||
{{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
|
{ { '3', '2' } }, { { '3', '3' } }, { { '3', '4' } }, { { '3', '5' } }, { { '3', '6' } }, { { '3', '7' } }, { { '3', '8' } }, { { '3', '9' } },
|
||||||
{{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
|
{ { '4', '0' } }, { { '4', '1' } }, { { '4', '2' } }, { { '4', '3' } }, { { '4', '4' } }, { { '4', '5' } }, { { '4', '6' } }, { { '4', '7' } },
|
||||||
{{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
|
{ { '4', '8' } }, { { '4', '9' } }, { { '5', '0' } }, { { '5', '1' } }, { { '5', '2' } }, { { '5', '3' } }, { { '5', '4' } }, { { '5', '5' } },
|
||||||
{{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
|
{ { '5', '6' } }, { { '5', '7' } }, { { '5', '8' } }, { { '5', '9' } }, { { '6', '0' } }, { { '6', '1' } }, { { '6', '2' } }, { { '6', '3' } },
|
||||||
{{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
|
{ { '6', '4' } }, { { '6', '5' } }, { { '6', '6' } }, { { '6', '7' } }, { { '6', '8' } }, { { '6', '9' } }, { { '7', '0' } }, { { '7', '1' } },
|
||||||
{{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
|
{ { '7', '2' } }, { { '7', '3' } }, { { '7', '4' } }, { { '7', '5' } }, { { '7', '6' } }, { { '7', '7' } }, { { '7', '8' } }, { { '7', '9' } },
|
||||||
{{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
|
{ { '8', '0' } }, { { '8', '1' } }, { { '8', '2' } }, { { '8', '3' } }, { { '8', '4' } }, { { '8', '5' } }, { { '8', '6' } }, { { '8', '7' } },
|
||||||
{{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
|
{ { '8', '8' } }, { { '8', '9' } }, { { '9', '0' } }, { { '9', '1' } }, { { '9', '2' } }, { { '9', '3' } }, { { '9', '4' } }, { { '9', '5' } },
|
||||||
}
|
{ { '9', '6' } }, { { '9', '7' } }, { { '9', '8' } }, { { '9', '9' } },
|
||||||
};
|
} };
|
||||||
|
|
||||||
// special case for "0"
|
// special case for "0"
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
@@ -810,9 +802,10 @@ class serializer
|
|||||||
// guaranteed to round-trip, using strtof and strtod, resp.
|
// guaranteed to round-trip, using strtof and strtod, resp.
|
||||||
//
|
//
|
||||||
// NB: The test below works if <long double> == <double>.
|
// NB: The test below works if <long double> == <double>.
|
||||||
static constexpr bool is_ieee_single_or_double
|
static constexpr bool is_ieee_single_or_double = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 &&
|
||||||
= (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
|
std::numeric_limits<number_float_t>::max_exponent == 128) ||
|
||||||
(std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
|
(std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 &&
|
||||||
|
std::numeric_limits<number_float_t>::max_exponent == 1024);
|
||||||
|
|
||||||
dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
|
dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
|
||||||
}
|
}
|
||||||
@@ -863,10 +856,7 @@ class serializer
|
|||||||
o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
|
o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
|
||||||
|
|
||||||
// determine if we need to append ".0"
|
// determine if we need to append ".0"
|
||||||
const bool value_is_int_like =
|
const bool value_is_int_like = std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1, [](char c) {
|
||||||
std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
|
|
||||||
[](char c)
|
|
||||||
{
|
|
||||||
return c == '.' || c == 'e';
|
return c == '.' || c == 'e';
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -899,32 +889,41 @@ class serializer
|
|||||||
*/
|
*/
|
||||||
static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
|
static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
|
||||||
{
|
{
|
||||||
static const std::array<std::uint8_t, 400> utf8d =
|
static const std::array<std::uint8_t, 400> utf8d = { {
|
||||||
{
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
{
|
0, // 00..1F
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
|
0, // 20..3F
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
|
0, // 40..5F
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
|
0, // 60..7F
|
||||||
8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||||
0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
|
9, // 80..9F
|
||||||
0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
|
7, // A0..BF
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
|
8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
|
2, // C0..DF
|
||||||
1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
|
0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3,
|
||||||
1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
|
0x3, // E0..EF
|
||||||
}
|
0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
|
||||||
};
|
0x8, // F0..FF
|
||||||
|
0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1,
|
||||||
|
0x1, // s0..s0
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
|
||||||
|
1, // s1..s2
|
||||||
|
1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, // s3..s4
|
||||||
|
1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1,
|
||||||
|
1, // s5..s6
|
||||||
|
1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1 // s7..s8
|
||||||
|
} };
|
||||||
|
|
||||||
JSON_ASSERT(byte < utf8d.size());
|
JSON_ASSERT(byte < utf8d.size());
|
||||||
const std::uint8_t type = utf8d[byte];
|
const std::uint8_t type = utf8d[byte];
|
||||||
|
|
||||||
codep = (state != UTF8_ACCEPT)
|
codep = (state != UTF8_ACCEPT) ? (byte & 0x3fu) | (codep << 6u) : (0xFFu >> type) & (byte);
|
||||||
? (byte & 0x3fu) | (codep << 6u)
|
|
||||||
: (0xFFu >> type) & (byte);
|
|
||||||
|
|
||||||
const std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
|
const std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
|
||||||
JSON_ASSERT(index < utf8d.size());
|
JSON_ASSERT(index < utf8d.size());
|
||||||
|
|||||||
@@ -77,56 +77,63 @@ using string_can_append_data = decltype(std::declval<StringType&>().append(std::
|
|||||||
template<typename StringType, typename Arg>
|
template<typename StringType, typename Arg>
|
||||||
using detect_string_can_append_data = is_detected<string_can_append_data, StringType, Arg>;
|
using detect_string_can_append_data = is_detected<string_can_append_data, StringType, Arg>;
|
||||||
|
|
||||||
template < typename OutStringType, typename Arg, typename... Args,
|
template<typename OutStringType,
|
||||||
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
|
typename Arg,
|
||||||
&& detect_string_can_append_op<OutStringType, Arg>::value, int > = 0 >
|
typename... Args,
|
||||||
|
enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && detect_string_can_append_op<OutStringType, Arg>::value, int> = 0>
|
||||||
inline void concat_into(OutStringType& out, Arg&& arg, Args&&... rest);
|
inline void concat_into(OutStringType& out, Arg&& arg, Args&&... rest);
|
||||||
|
|
||||||
template < typename OutStringType, typename Arg, typename... Args,
|
template<typename OutStringType,
|
||||||
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
|
typename Arg,
|
||||||
&& !detect_string_can_append_op<OutStringType, Arg>::value
|
typename... Args,
|
||||||
&& detect_string_can_append_iter<OutStringType, Arg>::value, int > = 0 >
|
enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && !detect_string_can_append_op<OutStringType, Arg>::value &&
|
||||||
|
detect_string_can_append_iter<OutStringType, Arg>::value,
|
||||||
|
int> = 0>
|
||||||
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest);
|
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest);
|
||||||
|
|
||||||
template < typename OutStringType, typename Arg, typename... Args,
|
template<typename OutStringType,
|
||||||
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
|
typename Arg,
|
||||||
&& !detect_string_can_append_op<OutStringType, Arg>::value
|
typename... Args,
|
||||||
&& !detect_string_can_append_iter<OutStringType, Arg>::value
|
enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && !detect_string_can_append_op<OutStringType, Arg>::value &&
|
||||||
&& detect_string_can_append_data<OutStringType, Arg>::value, int > = 0 >
|
!detect_string_can_append_iter<OutStringType, Arg>::value && detect_string_can_append_data<OutStringType, Arg>::value,
|
||||||
|
int> = 0>
|
||||||
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest);
|
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest);
|
||||||
|
|
||||||
template<typename OutStringType, typename Arg, typename... Args,
|
template<typename OutStringType, typename Arg, typename... Args, enable_if_t<detect_string_can_append<OutStringType, Arg>::value, int> = 0>
|
||||||
enable_if_t<detect_string_can_append<OutStringType, Arg>::value, int> = 0>
|
|
||||||
inline void concat_into(OutStringType& out, Arg&& arg, Args&&... rest)
|
inline void concat_into(OutStringType& out, Arg&& arg, Args&&... rest)
|
||||||
{
|
{
|
||||||
out.append(std::forward<Arg>(arg));
|
out.append(std::forward<Arg>(arg));
|
||||||
concat_into(out, std::forward<Args>(rest)...);
|
concat_into(out, std::forward<Args>(rest)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename OutStringType, typename Arg, typename... Args,
|
template<typename OutStringType,
|
||||||
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
|
typename Arg,
|
||||||
&& detect_string_can_append_op<OutStringType, Arg>::value, int > >
|
typename... Args,
|
||||||
|
enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && detect_string_can_append_op<OutStringType, Arg>::value, int>>
|
||||||
inline void concat_into(OutStringType& out, Arg&& arg, Args&&... rest)
|
inline void concat_into(OutStringType& out, Arg&& arg, Args&&... rest)
|
||||||
{
|
{
|
||||||
out += std::forward<Arg>(arg);
|
out += std::forward<Arg>(arg);
|
||||||
concat_into(out, std::forward<Args>(rest)...);
|
concat_into(out, std::forward<Args>(rest)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename OutStringType, typename Arg, typename... Args,
|
template<typename OutStringType,
|
||||||
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
|
typename Arg,
|
||||||
&& !detect_string_can_append_op<OutStringType, Arg>::value
|
typename... Args,
|
||||||
&& detect_string_can_append_iter<OutStringType, Arg>::value, int > >
|
enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && !detect_string_can_append_op<OutStringType, Arg>::value &&
|
||||||
|
detect_string_can_append_iter<OutStringType, Arg>::value,
|
||||||
|
int>>
|
||||||
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest)
|
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest)
|
||||||
{
|
{
|
||||||
out.append(arg.begin(), arg.end());
|
out.append(arg.begin(), arg.end());
|
||||||
concat_into(out, std::forward<Args>(rest)...);
|
concat_into(out, std::forward<Args>(rest)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename OutStringType, typename Arg, typename... Args,
|
template<typename OutStringType,
|
||||||
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
|
typename Arg,
|
||||||
&& !detect_string_can_append_op<OutStringType, Arg>::value
|
typename... Args,
|
||||||
&& !detect_string_can_append_iter<OutStringType, Arg>::value
|
enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && !detect_string_can_append_op<OutStringType, Arg>::value &&
|
||||||
&& detect_string_can_append_data<OutStringType, Arg>::value, int > >
|
!detect_string_can_append_iter<OutStringType, Arg>::value && detect_string_can_append_data<OutStringType, Arg>::value,
|
||||||
|
int>>
|
||||||
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest)
|
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest)
|
||||||
{
|
{
|
||||||
out.append(arg.data(), arg.size());
|
out.append(arg.data(), arg.size());
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ enforced with an assertion.**
|
|||||||
@since version 2.0.0
|
@since version 2.0.0
|
||||||
*/
|
*/
|
||||||
template<typename StringType>
|
template<typename StringType>
|
||||||
inline void replace_substring(StringType& s, const StringType& f,
|
inline void replace_substring(StringType& s, const StringType& f, const StringType& t)
|
||||||
const StringType& t)
|
|
||||||
{
|
{
|
||||||
JSON_ASSERT(!f.empty());
|
JSON_ASSERT(!f.empty());
|
||||||
for (auto pos = s.find(f); // find first occurrence of f
|
for (auto pos = s.find(f); // find first occurrence of f
|
||||||
|
|||||||
@@ -84,11 +84,16 @@ Returns an ordering that is similar to Python:
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
static constexpr std::array<std::uint8_t, 9> order = { {
|
static constexpr std::array<std::uint8_t, 9> order = { {
|
||||||
0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
|
0 /* null */,
|
||||||
1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
|
3 /* object */,
|
||||||
|
4 /* array */,
|
||||||
|
5 /* string */,
|
||||||
|
1 /* boolean */,
|
||||||
|
2 /* integer */,
|
||||||
|
2 /* unsigned */,
|
||||||
|
2 /* float */,
|
||||||
6 /* binary */
|
6 /* binary */
|
||||||
}
|
} };
|
||||||
};
|
|
||||||
|
|
||||||
const auto l_index = static_cast<std::size_t>(lhs);
|
const auto l_index = static_cast<std::size_t>(lhs);
|
||||||
const auto r_index = static_cast<std::size_t>(rhs);
|
const auto r_index = static_cast<std::size_t>(rhs);
|
||||||
|
|||||||
+286
-427
File diff suppressed because it is too large
Load Diff
@@ -36,16 +36,15 @@ struct adl_serializer;
|
|||||||
|
|
||||||
/// a class to store JSON values
|
/// a class to store JSON values
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/
|
/// @sa https://json.nlohmann.me/api/basic_json/
|
||||||
template<template<typename U, typename V, typename... Args> class ObjectType =
|
template<template<typename U, typename V, typename... Args> class ObjectType = std::map,
|
||||||
std::map,
|
|
||||||
template<typename U, typename... Args> class ArrayType = std::vector,
|
template<typename U, typename... Args> class ArrayType = std::vector,
|
||||||
class StringType = std::string, class BooleanType = bool,
|
class StringType = std::string,
|
||||||
|
class BooleanType = bool,
|
||||||
class NumberIntegerType = std::int64_t,
|
class NumberIntegerType = std::int64_t,
|
||||||
class NumberUnsignedType = std::uint64_t,
|
class NumberUnsignedType = std::uint64_t,
|
||||||
class NumberFloatType = double,
|
class NumberFloatType = double,
|
||||||
template<typename U> class AllocatorType = std::allocator,
|
template<typename U> class AllocatorType = std::allocator,
|
||||||
template<typename T, typename SFINAE = void> class JSONSerializer =
|
template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,
|
||||||
adl_serializer,
|
|
||||||
class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
|
class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
|
||||||
class CustomBaseClass = void>
|
class CustomBaseClass = void>
|
||||||
class basic_json;
|
class basic_json;
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ NLOHMANN_JSON_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
/// ordered_map: a minimal map-like container that preserves insertion order
|
/// ordered_map: a minimal map-like container that preserves insertion order
|
||||||
/// for use within nlohmann::basic_json<ordered_map>
|
/// for use within nlohmann::basic_json<ordered_map>
|
||||||
template <class Key, class T, class IgnoredLess = std::less<Key>,
|
template<class Key, class T, class IgnoredLess = std::less<Key>, class Allocator = std::allocator<std::pair<const Key, T>>>
|
||||||
class Allocator = std::allocator<std::pair<const Key, T>>>
|
|
||||||
struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
|
struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
|
||||||
{
|
{
|
||||||
using key_type = Key;
|
using key_type = Key;
|
||||||
@@ -43,13 +42,19 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
|
|
||||||
// Explicit constructors instead of `using Container::Container`
|
// Explicit constructors instead of `using Container::Container`
|
||||||
// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
|
// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
|
||||||
ordered_map() noexcept(noexcept(Container())) : Container{} {}
|
ordered_map() noexcept(noexcept(Container()))
|
||||||
explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
|
: Container{}
|
||||||
|
{}
|
||||||
|
explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc)))
|
||||||
|
: Container{ alloc }
|
||||||
|
{}
|
||||||
template<class It>
|
template<class It>
|
||||||
ordered_map(It first, It last, const Allocator& alloc = Allocator())
|
ordered_map(It first, It last, const Allocator& alloc = Allocator())
|
||||||
: Container{first, last, alloc} {}
|
: Container{ first, last, alloc }
|
||||||
|
{}
|
||||||
ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator())
|
ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator())
|
||||||
: Container{init, alloc} {}
|
: Container{ init, alloc }
|
||||||
|
{}
|
||||||
|
|
||||||
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
|
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
|
||||||
{
|
{
|
||||||
@@ -64,8 +69,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
return { std::prev(this->end()), true };
|
return { std::prev(this->end()), true };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class KeyType, detail::enable_if_t<
|
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
||||||
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
|
||||||
std::pair<iterator, bool> emplace(KeyType&& key, T&& t)
|
std::pair<iterator, bool> emplace(KeyType&& key, T&& t)
|
||||||
{
|
{
|
||||||
for (auto it = this->begin(); it != this->end(); ++it)
|
for (auto it = this->begin(); it != this->end(); ++it)
|
||||||
@@ -84,8 +88,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
return emplace(key, T{}).first->second;
|
return emplace(key, T{}).first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class KeyType, detail::enable_if_t<
|
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
||||||
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
|
||||||
T& operator[](KeyType&& key)
|
T& operator[](KeyType&& key)
|
||||||
{
|
{
|
||||||
return emplace(std::forward<KeyType>(key), T{}).first->second;
|
return emplace(std::forward<KeyType>(key), T{}).first->second;
|
||||||
@@ -96,8 +99,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
return at(key);
|
return at(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class KeyType, detail::enable_if_t<
|
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
||||||
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
|
||||||
const T& operator[](KeyType&& key) const
|
const T& operator[](KeyType&& key) const
|
||||||
{
|
{
|
||||||
return at(std::forward<KeyType>(key));
|
return at(std::forward<KeyType>(key));
|
||||||
@@ -116,8 +118,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
JSON_THROW(std::out_of_range("key not found"));
|
JSON_THROW(std::out_of_range("key not found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class KeyType, detail::enable_if_t<
|
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
||||||
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
|
||||||
T& at(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
|
T& at(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
|
||||||
{
|
{
|
||||||
for (auto it = this->begin(); it != this->end(); ++it)
|
for (auto it = this->begin(); it != this->end(); ++it)
|
||||||
@@ -144,8 +145,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
JSON_THROW(std::out_of_range("key not found"));
|
JSON_THROW(std::out_of_range("key not found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class KeyType, detail::enable_if_t<
|
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
||||||
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
|
||||||
const T& at(KeyType&& key) const // NOLINT(cppcoreguidelines-missing-std-forward)
|
const T& at(KeyType&& key) const // NOLINT(cppcoreguidelines-missing-std-forward)
|
||||||
{
|
{
|
||||||
for (auto it = this->begin(); it != this->end(); ++it)
|
for (auto it = this->begin(); it != this->end(); ++it)
|
||||||
@@ -178,8 +178,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class KeyType, detail::enable_if_t<
|
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
||||||
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
|
||||||
size_type erase(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
|
size_type erase(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
|
||||||
{
|
{
|
||||||
for (auto it = this->begin(); it != this->end(); ++it)
|
for (auto it = this->begin(); it != this->end(); ++it)
|
||||||
@@ -269,8 +268,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class KeyType, detail::enable_if_t<
|
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
||||||
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
|
||||||
size_type count(KeyType&& key) const // NOLINT(cppcoreguidelines-missing-std-forward)
|
size_type count(KeyType&& key) const // NOLINT(cppcoreguidelines-missing-std-forward)
|
||||||
{
|
{
|
||||||
for (auto it = this->begin(); it != this->end(); ++it)
|
for (auto it = this->begin(); it != this->end(); ++it)
|
||||||
@@ -295,8 +293,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
return Container::end();
|
return Container::end();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class KeyType, detail::enable_if_t<
|
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
||||||
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
|
|
||||||
iterator find(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
|
iterator find(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
|
||||||
{
|
{
|
||||||
for (auto it = this->begin(); it != this->end(); ++it)
|
for (auto it = this->begin(); it != this->end(); ++it)
|
||||||
@@ -340,8 +337,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename InputIt>
|
template<typename InputIt>
|
||||||
using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
|
using require_input_iter =
|
||||||
std::input_iterator_tag>::value>::type;
|
typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category, std::input_iterator_tag>::value>::type;
|
||||||
|
|
||||||
template<typename InputIt, typename = require_input_iter<InputIt>>
|
template<typename InputIt, typename = require_input_iter<InputIt>>
|
||||||
void insert(InputIt first, InputIt last)
|
void insert(InputIt first, InputIt last)
|
||||||
|
|||||||
+211
-537
File diff suppressed because it is too large
Load Diff
+5308
-2582
File diff suppressed because it is too large
Load Diff
@@ -24,8 +24,6 @@
|
|||||||
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
|
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This file contains all macro definitions affecting or depending on the ABI
|
// This file contains all macro definitions affecting or depending on the ABI
|
||||||
|
|
||||||
#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
|
#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
|
||||||
@@ -66,48 +64,34 @@
|
|||||||
|
|
||||||
// Construct the namespace ABI tags component
|
// Construct the namespace ABI tags component
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi##a##b
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi##a##b
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
|
|
||||||
|
|
||||||
#define NLOHMANN_JSON_ABI_TAGS \
|
#define NLOHMANN_JSON_ABI_TAGS NLOHMANN_JSON_ABI_TAGS_CONCAT(NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
|
||||||
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
|
|
||||||
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
|
|
||||||
|
|
||||||
// Construct the namespace version component
|
// Construct the namespace version component
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) _v##major##_##minor##_##patch
|
||||||
_v ## major ## _ ## minor ## _ ## patch
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
|
|
||||||
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
|
|
||||||
|
|
||||||
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION
|
#define NLOHMANN_JSON_NAMESPACE_VERSION
|
||||||
#else
|
#else
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION \
|
#define NLOHMANN_JSON_NAMESPACE_VERSION \
|
||||||
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
|
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH)
|
||||||
NLOHMANN_JSON_VERSION_MINOR, \
|
|
||||||
NLOHMANN_JSON_VERSION_PATCH)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Combine namespace components
|
// Combine namespace components
|
||||||
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a##b
|
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a##b
|
||||||
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
|
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
|
||||||
NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
|
|
||||||
|
|
||||||
#ifndef NLOHMANN_JSON_NAMESPACE
|
#ifndef NLOHMANN_JSON_NAMESPACE
|
||||||
#define NLOHMANN_JSON_NAMESPACE \
|
#define NLOHMANN_JSON_NAMESPACE nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT(NLOHMANN_JSON_ABI_TAGS, NLOHMANN_JSON_NAMESPACE_VERSION)
|
||||||
nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
|
|
||||||
NLOHMANN_JSON_ABI_TAGS, \
|
|
||||||
NLOHMANN_JSON_NAMESPACE_VERSION)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
|
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
|
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
|
||||||
namespace nlohmann \
|
namespace nlohmann \
|
||||||
{ \
|
{ \
|
||||||
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
|
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT(NLOHMANN_JSON_ABI_TAGS, NLOHMANN_JSON_NAMESPACE_VERSION) \
|
||||||
NLOHMANN_JSON_ABI_TAGS, \
|
|
||||||
NLOHMANN_JSON_NAMESPACE_VERSION) \
|
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -117,7 +101,6 @@
|
|||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief namespace for Niels Lohmann
|
@brief namespace for Niels Lohmann
|
||||||
@see https://github.com/nlohmann
|
@see https://github.com/nlohmann
|
||||||
@@ -137,16 +120,15 @@ struct adl_serializer;
|
|||||||
|
|
||||||
/// a class to store JSON values
|
/// a class to store JSON values
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/
|
/// @sa https://json.nlohmann.me/api/basic_json/
|
||||||
template<template<typename U, typename V, typename... Args> class ObjectType =
|
template<template<typename U, typename V, typename... Args> class ObjectType = std::map,
|
||||||
std::map,
|
|
||||||
template<typename U, typename... Args> class ArrayType = std::vector,
|
template<typename U, typename... Args> class ArrayType = std::vector,
|
||||||
class StringType = std::string, class BooleanType = bool,
|
class StringType = std::string,
|
||||||
|
class BooleanType = bool,
|
||||||
class NumberIntegerType = std::int64_t,
|
class NumberIntegerType = std::int64_t,
|
||||||
class NumberUnsignedType = std::uint64_t,
|
class NumberUnsignedType = std::uint64_t,
|
||||||
class NumberFloatType = double,
|
class NumberFloatType = double,
|
||||||
template<typename U> class AllocatorType = std::allocator,
|
template<typename U> class AllocatorType = std::allocator,
|
||||||
template<typename T, typename SFINAE = void> class JSONSerializer =
|
template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,
|
||||||
adl_serializer,
|
|
||||||
class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
|
class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
|
||||||
class CustomBaseClass = void>
|
class CustomBaseClass = void>
|
||||||
class basic_json;
|
class basic_json;
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
|
|
||||||
// define custom namespace
|
// define custom namespace
|
||||||
#define NLOHMANN_JSON_NAMESPACE nlohmann // this line may be omitted
|
#define NLOHMANN_JSON_NAMESPACE nlohmann // this line may be omitted
|
||||||
#define NLOHMANN_JSON_NAMESPACE_BEGIN namespace nlohmann {
|
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
|
||||||
|
namespace nlohmann \
|
||||||
|
{
|
||||||
#define NLOHMANN_JSON_NAMESPACE_END }
|
#define NLOHMANN_JSON_NAMESPACE_END }
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#include <nlohmann/json_fwd.hpp>
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,12 @@
|
|||||||
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
|
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
#include <benchmark/benchmark.h>
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <vector>
|
|
||||||
#include <test_data.hpp>
|
#include <test_data.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <benchmark/benchmark.h>
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
|
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include "Foo.hpp"
|
#include "Foo.hpp"
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
class Bar : public Foo {};
|
class Bar : public Foo
|
||||||
|
{};
|
||||||
|
|||||||
@@ -9,4 +9,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
class Foo {};
|
class Foo
|
||||||
|
{};
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ an implementation of the `LLVMFuzzerTestOneInput` function which processes a
|
|||||||
passed byte array.
|
passed byte array.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vector> // for vector
|
|
||||||
#include <cstdint> // for uint8_t
|
#include <cstdint> // for uint8_t
|
||||||
#include <iostream> // for cin
|
#include <iostream> // for cin
|
||||||
|
#include <vector> // for vector
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdio> // fopen, fclose, FILE
|
#include <cstdio> // fopen, fclose, FILE
|
||||||
|
#include <doctest.h>
|
||||||
#include <memory> // unique_ptr
|
#include <memory> // unique_ptr
|
||||||
#include <test_data.hpp>
|
#include <test_data.hpp>
|
||||||
#include <doctest.h>
|
|
||||||
|
|
||||||
namespace utils
|
namespace utils
|
||||||
{
|
{
|
||||||
@@ -24,7 +24,10 @@ inline bool check_testsuite_downloaded()
|
|||||||
|
|
||||||
TEST_CASE("check test suite is downloaded")
|
TEST_CASE("check test suite is downloaded")
|
||||||
{
|
{
|
||||||
REQUIRE_MESSAGE(utils::check_testsuite_downloaded(), "Test data not found in '" TEST_DATA_DIRECTORY "'. Please execute target 'download_test_data' before running this test suite. See <https://github.com/nlohmann/json#execute-unit-tests> for more information.");
|
REQUIRE_MESSAGE(
|
||||||
|
utils::check_testsuite_downloaded(),
|
||||||
|
"Test data not found in '" TEST_DATA_DIRECTORY
|
||||||
|
"'. Please execute target 'download_test_data' before running this test suite. See <https://github.com/nlohmann/json#execute-unit-tests> for more information.");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|||||||
@@ -92,10 +92,10 @@ TEST_CASE("32bit")
|
|||||||
REQUIRE(SIZE_MAX == 0xffffffff);
|
REQUIRE(SIZE_MAX == 0xffffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE_INVOKE(value_in_range_of_test, \
|
TEST_CASE_TEMPLATE_INVOKE(value_in_range_of_test,
|
||||||
trait_test_arg<std::size_t, std::int32_t, false, true>, \
|
trait_test_arg<std::size_t, std::int32_t, false, true>,
|
||||||
trait_test_arg<std::size_t, std::uint32_t, true, true>, \
|
trait_test_arg<std::size_t, std::uint32_t, true, true>,
|
||||||
trait_test_arg<std::size_t, std::int64_t, false, false>, \
|
trait_test_arg<std::size_t, std::int64_t, false, false>,
|
||||||
trait_test_arg<std::size_t, std::uint64_t, true, false>);
|
trait_test_arg<std::size_t, std::uint64_t, true, false>);
|
||||||
|
|
||||||
TEST_CASE("BJData")
|
TEST_CASE("BJData")
|
||||||
@@ -110,10 +110,14 @@ TEST_CASE("BJData")
|
|||||||
std::vector<uint8_t> const vMX = { '[', '$', 'U', '#', '[', 'M', 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 'U', 0x01, ']' };
|
std::vector<uint8_t> const vMX = { '[', '$', 'U', '#', '[', 'M', 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 'U', 0x01, ']' };
|
||||||
|
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM),
|
||||||
|
"[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow",
|
||||||
|
json::out_of_range&);
|
||||||
CHECK(json::from_bjdata(vM, true, false).is_discarded());
|
CHECK(json::from_bjdata(vM, true, false).is_discarded());
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vMX), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vMX),
|
||||||
|
"[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow",
|
||||||
|
json::out_of_range&);
|
||||||
CHECK(json::from_bjdata(vMX, true, false).is_discarded());
|
CHECK(json::from_bjdata(vMX, true, false).is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,10 +127,14 @@ TEST_CASE("BJData")
|
|||||||
std::vector<uint8_t> const vM = { '[', '$', 'M', '#', '[', 'I', 0x00, 0x20, 'M', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF, ']' };
|
std::vector<uint8_t> const vM = { '[', '$', 'M', '#', '[', 'I', 0x00, 0x20, 'M', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF, ']' };
|
||||||
|
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vL), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vL),
|
||||||
|
"[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow",
|
||||||
|
json::out_of_range&);
|
||||||
CHECK(json::from_bjdata(vL, true, false).is_discarded());
|
CHECK(json::from_bjdata(vL, true, false).is_discarded());
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM),
|
||||||
|
"[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow",
|
||||||
|
json::out_of_range&);
|
||||||
CHECK(json::from_bjdata(vM, true, false).is_discarded());
|
CHECK(json::from_bjdata(vM, true, false).is_discarded());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,36 +21,30 @@ TEST_CASE("algorithms")
|
|||||||
{
|
{
|
||||||
SECTION("std::all_of")
|
SECTION("std::all_of")
|
||||||
{
|
{
|
||||||
CHECK(std::all_of(j_array.begin(), j_array.end(), [](const json & value)
|
CHECK(std::all_of(j_array.begin(), j_array.end(), [](const json& value) {
|
||||||
{
|
|
||||||
return !value.empty();
|
return !value.empty();
|
||||||
}));
|
}));
|
||||||
CHECK(std::all_of(j_object.begin(), j_object.end(), [](const json & value)
|
CHECK(std::all_of(j_object.begin(), j_object.end(), [](const json& value) {
|
||||||
{
|
|
||||||
return value.type() == json::value_t::number_integer;
|
return value.type() == json::value_t::number_integer;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("std::any_of")
|
SECTION("std::any_of")
|
||||||
{
|
{
|
||||||
CHECK(std::any_of(j_array.begin(), j_array.end(), [](const json & value)
|
CHECK(std::any_of(j_array.begin(), j_array.end(), [](const json& value) {
|
||||||
{
|
|
||||||
return value.is_string() && value.get<std::string>() == "foo";
|
return value.is_string() && value.get<std::string>() == "foo";
|
||||||
}));
|
}));
|
||||||
CHECK(std::any_of(j_object.begin(), j_object.end(), [](const json & value)
|
CHECK(std::any_of(j_object.begin(), j_object.end(), [](const json& value) {
|
||||||
{
|
|
||||||
return value.get<int>() > 1;
|
return value.get<int>() > 1;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("std::none_of")
|
SECTION("std::none_of")
|
||||||
{
|
{
|
||||||
CHECK(std::none_of(j_array.begin(), j_array.end(), [](const json & value)
|
CHECK(std::none_of(j_array.begin(), j_array.end(), [](const json& value) {
|
||||||
{
|
|
||||||
return value.empty();
|
return value.empty();
|
||||||
}));
|
}));
|
||||||
CHECK(std::none_of(j_object.begin(), j_object.end(), [](const json & value)
|
CHECK(std::none_of(j_object.begin(), j_object.end(), [](const json& value) {
|
||||||
{
|
|
||||||
return value.get<int>() <= 0;
|
return value.get<int>() <= 0;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -61,8 +55,7 @@ TEST_CASE("algorithms")
|
|||||||
{
|
{
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
|
|
||||||
std::for_each(j_array.cbegin(), j_array.cend(), [&sum](const json & value)
|
std::for_each(j_array.cbegin(), j_array.cend(), [&sum](const json& value) {
|
||||||
{
|
|
||||||
if (value.is_number())
|
if (value.is_number())
|
||||||
{
|
{
|
||||||
sum += static_cast<int>(value);
|
sum += static_cast<int>(value);
|
||||||
@@ -74,8 +67,7 @@ TEST_CASE("algorithms")
|
|||||||
|
|
||||||
SECTION("writing")
|
SECTION("writing")
|
||||||
{
|
{
|
||||||
auto add17 = [](json & value)
|
auto add17 = [](json& value) {
|
||||||
{
|
|
||||||
if (value.is_array())
|
if (value.is_array())
|
||||||
{
|
{
|
||||||
value.push_back(17);
|
value.push_back(17);
|
||||||
@@ -95,12 +87,10 @@ TEST_CASE("algorithms")
|
|||||||
|
|
||||||
SECTION("std::count_if")
|
SECTION("std::count_if")
|
||||||
{
|
{
|
||||||
CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json & value)
|
CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json& value) {
|
||||||
{
|
|
||||||
return (value.is_number());
|
return (value.is_number());
|
||||||
}) == 3);
|
}) == 3);
|
||||||
CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json&)
|
CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json&) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}) == 9);
|
}) == 9);
|
||||||
}
|
}
|
||||||
@@ -127,9 +117,7 @@ TEST_CASE("algorithms")
|
|||||||
// compare objects only by size of its elements
|
// compare objects only by size of its elements
|
||||||
json j_array2 = { 13, 29, 3, { "Hello", "World" }, true, false, { { "one", 1 }, { "two", 2 }, { "three", 3 } }, "foo", "baz" };
|
json j_array2 = { 13, 29, 3, { "Hello", "World" }, true, false, { { "one", 1 }, { "two", 2 }, { "three", 3 } }, "foo", "baz" };
|
||||||
CHECK(!std::equal(j_array.begin(), j_array.end(), j_array2.begin()));
|
CHECK(!std::equal(j_array.begin(), j_array.end(), j_array2.begin()));
|
||||||
CHECK(std::equal(j_array.begin(), j_array.end(), j_array2.begin(),
|
CHECK(std::equal(j_array.begin(), j_array.end(), j_array2.begin(), [](const json& a, const json& b) {
|
||||||
[](const json & a, const json & b)
|
|
||||||
{
|
|
||||||
return (a.size() == b.size());
|
return (a.size() == b.size());
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -143,9 +131,7 @@ TEST_CASE("algorithms")
|
|||||||
|
|
||||||
SECTION("std::find_if")
|
SECTION("std::find_if")
|
||||||
{
|
{
|
||||||
auto it = std::find_if(j_array.begin(), j_array.end(),
|
auto it = std::find_if(j_array.begin(), j_array.end(), [](const json& value) {
|
||||||
[](const json & value)
|
|
||||||
{
|
|
||||||
return value.is_boolean();
|
return value.is_boolean();
|
||||||
});
|
});
|
||||||
CHECK(std::distance(j_array.begin(), it) == 4);
|
CHECK(std::distance(j_array.begin(), it) == 4);
|
||||||
@@ -153,9 +139,7 @@ TEST_CASE("algorithms")
|
|||||||
|
|
||||||
SECTION("std::find_if_not")
|
SECTION("std::find_if_not")
|
||||||
{
|
{
|
||||||
auto it = std::find_if_not(j_array.begin(), j_array.end(),
|
auto it = std::find_if_not(j_array.begin(), j_array.end(), [](const json& value) {
|
||||||
[](const json & value)
|
|
||||||
{
|
|
||||||
return value.is_number();
|
return value.is_number();
|
||||||
});
|
});
|
||||||
CHECK(std::distance(j_array.begin(), it) == 3);
|
CHECK(std::distance(j_array.begin(), it) == 3);
|
||||||
@@ -164,9 +148,7 @@ TEST_CASE("algorithms")
|
|||||||
SECTION("std::adjacent_find")
|
SECTION("std::adjacent_find")
|
||||||
{
|
{
|
||||||
CHECK(std::adjacent_find(j_array.begin(), j_array.end()) == j_array.end());
|
CHECK(std::adjacent_find(j_array.begin(), j_array.end()) == j_array.end());
|
||||||
CHECK(std::adjacent_find(j_array.begin(), j_array.end(),
|
CHECK(std::adjacent_find(j_array.begin(), j_array.end(), [](const json& v1, const json& v2) {
|
||||||
[](const json & v1, const json & v2)
|
|
||||||
{
|
|
||||||
return v1.type() == v2.type();
|
return v1.type() == v2.type();
|
||||||
}) == j_array.begin());
|
}) == j_array.begin());
|
||||||
}
|
}
|
||||||
@@ -188,8 +170,7 @@ TEST_CASE("algorithms")
|
|||||||
|
|
||||||
SECTION("std::partition")
|
SECTION("std::partition")
|
||||||
{
|
{
|
||||||
auto it = std::partition(j_array.begin(), j_array.end(), [](const json & v)
|
auto it = std::partition(j_array.begin(), j_array.end(), [](const json& v) {
|
||||||
{
|
|
||||||
return v.is_string();
|
return v.is_string();
|
||||||
});
|
});
|
||||||
CHECK(std::distance(j_array.begin(), it) == 2);
|
CHECK(std::distance(j_array.begin(), it) == 2);
|
||||||
@@ -211,8 +192,7 @@ TEST_CASE("algorithms")
|
|||||||
SECTION("with user-defined comparison")
|
SECTION("with user-defined comparison")
|
||||||
{
|
{
|
||||||
json j = { 3, { { "one", 1 }, { "two", 2 } }, { 1, 2, 3 }, nullptr };
|
json j = { 3, { { "one", 1 }, { "two", 2 } }, { 1, 2, 3 }, nullptr };
|
||||||
std::sort(j.begin(), j.end(), [](const json & a, const json & b)
|
std::sort(j.begin(), j.end(), [](const json& a, const json& b) {
|
||||||
{
|
|
||||||
return a.size() < b.size();
|
return a.size() < b.size();
|
||||||
});
|
});
|
||||||
CHECK(j == json({ nullptr, 3, { { "one", 1 }, { "two", 2 } }, { 1, 2, 3 } }));
|
CHECK(j == json({ nullptr, 3, { { "one", 1 }, { "two", 2 } }, { 1, 2, 3 } }));
|
||||||
@@ -221,7 +201,9 @@ TEST_CASE("algorithms")
|
|||||||
SECTION("sorting an object")
|
SECTION("sorting an object")
|
||||||
{
|
{
|
||||||
json j({ { "one", 1 }, { "two", 2 } });
|
json j({ { "one", 1 }, { "two", 2 } });
|
||||||
CHECK_THROWS_WITH_AS(std::sort(j.begin(), j.end()), "[json.exception.invalid_iterator.209] cannot use offsets with object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(std::sort(j.begin(), j.end()),
|
||||||
|
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,8 +317,7 @@ TEST_CASE("algorithms")
|
|||||||
json dest_arr;
|
json dest_arr;
|
||||||
const json source_arr = { 0, 3, 6, 9, 12, 15, 20 };
|
const json source_arr = { 0, 3, 6, 9, 12, 15, 20 };
|
||||||
|
|
||||||
std::copy_if(source_arr.begin(), source_arr.end(), std::back_inserter(dest_arr), [](const json & _value)
|
std::copy_if(source_arr.begin(), source_arr.end(), std::back_inserter(dest_arr), [](const json& _value) {
|
||||||
{
|
|
||||||
return _value.get<int>() % 3 == 0;
|
return _value.get<int>() % 3 == 0;
|
||||||
});
|
});
|
||||||
CHECK(dest_arr == json({ 0, 3, 6, 9, 12, 15 }));
|
CHECK(dest_arr == json({ 0, 3, 6, 9, 12, 15 }));
|
||||||
@@ -349,7 +330,6 @@ TEST_CASE("algorithms")
|
|||||||
|
|
||||||
std::copy_n(source_arr.begin(), numToCopy, std::back_inserter(dest_arr));
|
std::copy_n(source_arr.begin(), numToCopy, std::back_inserter(dest_arr));
|
||||||
CHECK(dest_arr == json{ 0, 1 });
|
CHECK(dest_arr == json{ 0, 1 });
|
||||||
|
|
||||||
}
|
}
|
||||||
SECTION("copy n chars")
|
SECTION("copy n chars")
|
||||||
{
|
{
|
||||||
@@ -361,5 +341,4 @@ TEST_CASE("algorithms")
|
|||||||
CHECK(dest_arr == json{ '1', '2', '3', '4' });
|
CHECK(dest_arr == json{ '1', '2', '3', '4' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ struct bad_allocator : std::allocator<T>
|
|||||||
using std::allocator<T>::allocator;
|
using std::allocator<T>::allocator;
|
||||||
|
|
||||||
bad_allocator() = default;
|
bad_allocator() = default;
|
||||||
template<class U> bad_allocator(const bad_allocator<U>& /*unused*/) { }
|
template<class U>
|
||||||
|
bad_allocator(const bad_allocator<U>& /*unused*/)
|
||||||
|
{}
|
||||||
|
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
void construct(T* /*unused*/, Args&&... /*unused*/) // NOLINT(cppcoreguidelines-missing-std-forward)
|
void construct(T* /*unused*/, Args&&... /*unused*/) // NOLINT(cppcoreguidelines-missing-std-forward)
|
||||||
@@ -42,14 +44,7 @@ TEST_CASE("bad_alloc")
|
|||||||
SECTION("bad_alloc")
|
SECTION("bad_alloc")
|
||||||
{
|
{
|
||||||
// create JSON type using the throwing allocator
|
// create JSON type using the throwing allocator
|
||||||
using bad_json = nlohmann::basic_json<std::map,
|
using bad_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, bad_allocator>;
|
||||||
std::vector,
|
|
||||||
std::string,
|
|
||||||
bool,
|
|
||||||
std::int64_t,
|
|
||||||
std::uint64_t,
|
|
||||||
double,
|
|
||||||
bad_allocator>;
|
|
||||||
|
|
||||||
// creating an object should throw
|
// creating an object should throw
|
||||||
CHECK_THROWS_AS(bad_json(bad_json::value_t::object), std::bad_alloc&);
|
CHECK_THROWS_AS(bad_json(bad_json::value_t::object), std::bad_alloc&);
|
||||||
@@ -123,14 +118,7 @@ void my_allocator_clean_up(T* p)
|
|||||||
TEST_CASE("controlled bad_alloc")
|
TEST_CASE("controlled bad_alloc")
|
||||||
{
|
{
|
||||||
// create JSON type using the throwing allocator
|
// create JSON type using the throwing allocator
|
||||||
using my_json = nlohmann::basic_json<std::map,
|
using my_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, my_allocator>;
|
||||||
std::vector,
|
|
||||||
std::string,
|
|
||||||
bool,
|
|
||||||
std::int64_t,
|
|
||||||
std::uint64_t,
|
|
||||||
double,
|
|
||||||
my_allocator>;
|
|
||||||
|
|
||||||
SECTION("class json_value")
|
SECTION("class json_value")
|
||||||
{
|
{
|
||||||
@@ -226,7 +214,8 @@ struct allocator_no_forward : std::allocator<T>
|
|||||||
{
|
{
|
||||||
allocator_no_forward() = default;
|
allocator_no_forward() = default;
|
||||||
template<class U>
|
template<class U>
|
||||||
allocator_no_forward(allocator_no_forward<U> /*unused*/) {}
|
allocator_no_forward(allocator_no_forward<U> /*unused*/)
|
||||||
|
{}
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
struct rebind
|
struct rebind
|
||||||
@@ -247,14 +236,7 @@ TEST_CASE("bad my_allocator::construct")
|
|||||||
{
|
{
|
||||||
SECTION("my_allocator::construct doesn't forward")
|
SECTION("my_allocator::construct doesn't forward")
|
||||||
{
|
{
|
||||||
using bad_alloc_json = nlohmann::basic_json<std::map,
|
using bad_alloc_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, allocator_no_forward>;
|
||||||
std::vector,
|
|
||||||
std::string,
|
|
||||||
bool,
|
|
||||||
std::int64_t,
|
|
||||||
std::uint64_t,
|
|
||||||
double,
|
|
||||||
allocator_no_forward>;
|
|
||||||
|
|
||||||
bad_alloc_json j;
|
bad_alloc_json j;
|
||||||
j["test"] = bad_alloc_json::array_t();
|
j["test"] = bad_alloc_json::array_t();
|
||||||
|
|||||||
@@ -30,9 +30,15 @@ class alt_string
|
|||||||
|
|
||||||
static constexpr auto npos = static_cast<std::size_t>(-1);
|
static constexpr auto npos = static_cast<std::size_t>(-1);
|
||||||
|
|
||||||
alt_string(const char* str): str_impl(str) {}
|
alt_string(const char* str)
|
||||||
alt_string(const char* str, std::size_t count): str_impl(str, count) {}
|
: str_impl(str)
|
||||||
alt_string(size_t count, char chr): str_impl(count, chr) {}
|
{}
|
||||||
|
alt_string(const char* str, std::size_t count)
|
||||||
|
: str_impl(str, count)
|
||||||
|
{}
|
||||||
|
alt_string(size_t count, char chr)
|
||||||
|
: str_impl(count, chr)
|
||||||
|
{}
|
||||||
alt_string() = default;
|
alt_string() = default;
|
||||||
|
|
||||||
template<typename... TParams>
|
template<typename... TParams>
|
||||||
@@ -168,16 +174,7 @@ void int_to_string(alt_string& target, std::size_t value)
|
|||||||
target = std::to_string(value).c_str();
|
target = std::to_string(value).c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
using alt_json = nlohmann::basic_json <
|
using alt_json = nlohmann::basic_json<std::map, std::vector, alt_string, bool, std::int64_t, std::uint64_t, double, std::allocator, nlohmann::adl_serializer>;
|
||||||
std::map,
|
|
||||||
std::vector,
|
|
||||||
alt_string,
|
|
||||||
bool,
|
|
||||||
std::int64_t,
|
|
||||||
std::uint64_t,
|
|
||||||
double,
|
|
||||||
std::allocator,
|
|
||||||
nlohmann::adl_serializer >;
|
|
||||||
|
|
||||||
bool operator<(const char* op1, const alt_string& op2) noexcept
|
bool operator<(const char* op1, const alt_string& op2) noexcept
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,11 @@ DOCTEST_CLANG_SUPPRESS_WARNING("-Wstrict-overflow")
|
|||||||
static int assert_counter;
|
static int assert_counter;
|
||||||
|
|
||||||
/// set failure variable to true instead of calling assert(x)
|
/// set failure variable to true instead of calling assert(x)
|
||||||
#define JSON_ASSERT(x) {if (!(x)) ++assert_counter; }
|
#define JSON_ASSERT(x) \
|
||||||
|
{ \
|
||||||
|
if (!(x)) \
|
||||||
|
++assert_counter; \
|
||||||
|
}
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
TEST_CASE("Binary Formats" * doctest::skip())
|
TEST_CASE("Binary Formats" * doctest::skip())
|
||||||
{
|
{
|
||||||
|
|||||||
+558
-451
File diff suppressed because it is too large
Load Diff
+444
-325
File diff suppressed because it is too large
Load Diff
+374
-276
File diff suppressed because it is too large
Load Diff
@@ -462,7 +462,6 @@ TEST_CASE("iterator class")
|
|||||||
using Iter = nlohmann::detail::json_reverse_iterator<Base>;
|
using Iter = nlohmann::detail::json_reverse_iterator<Base>;
|
||||||
CHECK_FALSE(is_detected<can_post_decrement_temporary, Iter&>::value);
|
CHECK_FALSE(is_detected<can_post_decrement_temporary, Iter&>::value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+501
-232
@@ -131,7 +131,8 @@ class SaxEventLogger
|
|||||||
class SaxCountdown : public nlohmann::json::json_sax_t
|
class SaxCountdown : public nlohmann::json::json_sax_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SaxCountdown(const int count) : events_left(count)
|
explicit SaxCountdown(const int count)
|
||||||
|
: events_left(count)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool null() override
|
bool null() override
|
||||||
@@ -249,8 +250,7 @@ bool accept_helper(const std::string& s)
|
|||||||
CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept(false) == !el.errored);
|
CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept(false) == !el.errored);
|
||||||
|
|
||||||
// 5. parse with simple callback
|
// 5. parse with simple callback
|
||||||
json::parser_callback_t const cb = [](int /*unused*/, json::parse_event_t /*unused*/, json& /*unused*/) noexcept
|
json::parser_callback_t const cb = [](int /*unused*/, json::parse_event_t /*unused*/, json& /*unused*/) noexcept {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
json const j_cb = json::parse(s, cb, false);
|
json const j_cb = json::parse(s, cb, false);
|
||||||
@@ -359,48 +359,156 @@ TEST_CASE("parser class")
|
|||||||
SECTION("errors")
|
SECTION("errors")
|
||||||
{
|
{
|
||||||
// error: tab in string
|
// error: tab in string
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\t\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t; last read: '\"<U+0009>'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\t\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t; last read: '\"<U+0009>'",
|
||||||
|
json::parse_error&);
|
||||||
// error: newline in string
|
// error: newline in string
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\n\""), "[json.exception.parse_error.101] parse error at line 2, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n; last read: '\"<U+000A>'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\r\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r; last read: '\"<U+000D>'", json::parse_error&);
|
parser_helper("\"\n\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 2, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n; last read: '\"<U+000A>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\r\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r; last read: '\"<U+000D>'",
|
||||||
|
json::parse_error&);
|
||||||
// error: backspace in string
|
// error: backspace in string
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\b\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b; last read: '\"<U+0008>'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\b\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b; last read: '\"<U+0008>'",
|
||||||
|
json::parse_error&);
|
||||||
// improve code coverage
|
// improve code coverage
|
||||||
CHECK_THROWS_AS(parser_helper("\uFF01"), json::parse_error&);
|
CHECK_THROWS_AS(parser_helper("\uFF01"), json::parse_error&);
|
||||||
CHECK_THROWS_AS(parser_helper("[-4:1,]"), json::parse_error&);
|
CHECK_THROWS_AS(parser_helper("[-4:1,]"), json::parse_error&);
|
||||||
// unescaped control characters
|
// unescaped control characters
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x00\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '\"'", json::parse_error&); // NOLINT(bugprone-string-literal-with-embedded-nul)
|
CHECK_THROWS_WITH_AS(
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x01\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0001 (SOH) must be escaped to \\u0001; last read: '\"<U+0001>'", json::parse_error&);
|
parser_helper("\"\x00\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x02\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0002 (STX) must be escaped to \\u0002; last read: '\"<U+0002>'", json::parse_error&);
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '\"'",
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x03\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0003 (ETX) must be escaped to \\u0003; last read: '\"<U+0003>'", json::parse_error&);
|
json::parse_error&); // NOLINT(bugprone-string-literal-with-embedded-nul)
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x04\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0004 (EOT) must be escaped to \\u0004; last read: '\"<U+0004>'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x05\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0005 (ENQ) must be escaped to \\u0005; last read: '\"<U+0005>'", json::parse_error&);
|
parser_helper("\"\x01\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x06\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0006 (ACK) must be escaped to \\u0006; last read: '\"<U+0006>'", json::parse_error&);
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0001 (SOH) must be escaped to \\u0001; last read: '\"<U+0001>'",
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x07\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0007 (BEL) must be escaped to \\u0007; last read: '\"<U+0007>'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x08\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b; last read: '\"<U+0008>'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x09\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t; last read: '\"<U+0009>'", json::parse_error&);
|
parser_helper("\"\x02\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x0a\""), "[json.exception.parse_error.101] parse error at line 2, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n; last read: '\"<U+000A>'", json::parse_error&);
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0002 (STX) must be escaped to \\u0002; last read: '\"<U+0002>'",
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x0b\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000B (VT) must be escaped to \\u000B; last read: '\"<U+000B>'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x0c\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f; last read: '\"<U+000C>'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x0d\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r; last read: '\"<U+000D>'", json::parse_error&);
|
parser_helper("\"\x03\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x0e\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000E (SO) must be escaped to \\u000E; last read: '\"<U+000E>'", json::parse_error&);
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0003 (ETX) must be escaped to \\u0003; last read: '\"<U+0003>'",
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x0f\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000F (SI) must be escaped to \\u000F; last read: '\"<U+000F>'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x10\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0010 (DLE) must be escaped to \\u0010; last read: '\"<U+0010>'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x11\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0011 (DC1) must be escaped to \\u0011; last read: '\"<U+0011>'", json::parse_error&);
|
parser_helper("\"\x04\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x12\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0012 (DC2) must be escaped to \\u0012; last read: '\"<U+0012>'", json::parse_error&);
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0004 (EOT) must be escaped to \\u0004; last read: '\"<U+0004>'",
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x13\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0013 (DC3) must be escaped to \\u0013; last read: '\"<U+0013>'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x14\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0014 (DC4) must be escaped to \\u0014; last read: '\"<U+0014>'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x15\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0015 (NAK) must be escaped to \\u0015; last read: '\"<U+0015>'", json::parse_error&);
|
parser_helper("\"\x05\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x16\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0016 (SYN) must be escaped to \\u0016; last read: '\"<U+0016>'", json::parse_error&);
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0005 (ENQ) must be escaped to \\u0005; last read: '\"<U+0005>'",
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x17\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0017 (ETB) must be escaped to \\u0017; last read: '\"<U+0017>'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x18\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0018 (CAN) must be escaped to \\u0018; last read: '\"<U+0018>'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x19\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0019 (EM) must be escaped to \\u0019; last read: '\"<U+0019>'", json::parse_error&);
|
parser_helper("\"\x06\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x1a\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001A (SUB) must be escaped to \\u001A; last read: '\"<U+001A>'", json::parse_error&);
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0006 (ACK) must be escaped to \\u0006; last read: '\"<U+0006>'",
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x1b\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001B (ESC) must be escaped to \\u001B; last read: '\"<U+001B>'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x1c\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001C (FS) must be escaped to \\u001C; last read: '\"<U+001C>'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x1d\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001D (GS) must be escaped to \\u001D; last read: '\"<U+001D>'", json::parse_error&);
|
parser_helper("\"\x07\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x1e\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001E (RS) must be escaped to \\u001E; last read: '\"<U+001E>'", json::parse_error&);
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0007 (BEL) must be escaped to \\u0007; last read: '\"<U+0007>'",
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\x1f\""), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001F (US) must be escaped to \\u001F; last read: '\"<U+001F>'", json::parse_error&);
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x08\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b; last read: '\"<U+0008>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x09\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t; last read: '\"<U+0009>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x0a\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 2, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n; last read: '\"<U+000A>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x0b\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000B (VT) must be escaped to \\u000B; last read: '\"<U+000B>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x0c\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f; last read: '\"<U+000C>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x0d\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r; last read: '\"<U+000D>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x0e\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000E (SO) must be escaped to \\u000E; last read: '\"<U+000E>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x0f\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+000F (SI) must be escaped to \\u000F; last read: '\"<U+000F>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x10\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0010 (DLE) must be escaped to \\u0010; last read: '\"<U+0010>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x11\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0011 (DC1) must be escaped to \\u0011; last read: '\"<U+0011>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x12\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0012 (DC2) must be escaped to \\u0012; last read: '\"<U+0012>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x13\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0013 (DC3) must be escaped to \\u0013; last read: '\"<U+0013>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x14\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0014 (DC4) must be escaped to \\u0014; last read: '\"<U+0014>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x15\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0015 (NAK) must be escaped to \\u0015; last read: '\"<U+0015>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x16\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0016 (SYN) must be escaped to \\u0016; last read: '\"<U+0016>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x17\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0017 (ETB) must be escaped to \\u0017; last read: '\"<U+0017>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x18\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0018 (CAN) must be escaped to \\u0018; last read: '\"<U+0018>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x19\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0019 (EM) must be escaped to \\u0019; last read: '\"<U+0019>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x1a\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001A (SUB) must be escaped to \\u001A; last read: '\"<U+001A>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x1b\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001B (ESC) must be escaped to \\u001B; last read: '\"<U+001B>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x1c\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001C (FS) must be escaped to \\u001C; last read: '\"<U+001C>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x1d\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001D (GS) must be escaped to \\u001D; last read: '\"<U+001D>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x1e\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001E (RS) must be escaped to \\u001E; last read: '\"<U+001E>'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\x1f\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+001F (US) must be escaped to \\u001F; last read: '\"<U+001F>'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
SECTION("additional test for null byte")
|
SECTION("additional test for null byte")
|
||||||
{
|
{
|
||||||
@@ -411,7 +519,10 @@ TEST_CASE("parser class")
|
|||||||
std::string s = "\"1\"";
|
std::string s = "\"1\"";
|
||||||
s[1] = '\0';
|
s[1] = '\0';
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(s.begin(), s.end()), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0000 (NUL) must be escaped to \\u0000; last read: '\"<U+0000>'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(s.begin(), s.end()),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0000 (NUL) must be escaped to \\u0000; last read: '\"<U+0000>'",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,7 +693,9 @@ TEST_CASE("parser class")
|
|||||||
SECTION("overflow")
|
SECTION("overflow")
|
||||||
{
|
{
|
||||||
// overflows during parsing yield an exception
|
// overflows during parsing yield an exception
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("1.18973e+4932").empty(), "[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(parser_helper("1.18973e+4932").empty(),
|
||||||
|
"[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'",
|
||||||
|
json::out_of_range&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("invalid numbers")
|
SECTION("invalid numbers")
|
||||||
@@ -591,40 +704,74 @@ TEST_CASE("parser class")
|
|||||||
CHECK_THROWS_AS(parser_helper("+1"), json::parse_error&);
|
CHECK_THROWS_AS(parser_helper("+1"), json::parse_error&);
|
||||||
CHECK_THROWS_AS(parser_helper("+0"), json::parse_error&);
|
CHECK_THROWS_AS(parser_helper("+0"), json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("01"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - unexpected number literal; expected end of input", json::parse_error&);
|
parser_helper("01"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-01"),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - unexpected number literal; expected end of input",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - unexpected number literal; expected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("--1"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '--'", json::parse_error&);
|
parser_helper("-01"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("1."),
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - unexpected number literal; expected end of input",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '1.'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("1E"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E'", json::parse_error&);
|
parser_helper("--1"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("1E-"),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '--'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '1E-'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("1.E1"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '1.E'", json::parse_error&);
|
parser_helper("1."),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-1E"),
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '1.'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '-1E'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-0E#"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '-0E#'", json::parse_error&);
|
parser_helper("1E"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-0E-#"),
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '-0E-#'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-0#"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: '-0#'; expected end of input", json::parse_error&);
|
parser_helper("1E-"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-0.0:"),
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '1E-'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - unexpected ':'; expected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-0.0Z"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: '-0.0Z'; expected end of input", json::parse_error&);
|
parser_helper("1.E1"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-0E123:"),
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '1.E'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - unexpected ':'; expected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-0e0-:"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-:'; expected end of input", json::parse_error&);
|
parser_helper("-1E"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-0e-:"),
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '-1E'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '-0e-:'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-0f"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: '-0f'; expected end of input", json::parse_error&);
|
parser_helper("-0E#"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '-0E#'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("-0E-#"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '-0E-#'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("-0#"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: '-0#'; expected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("-0.0:"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - unexpected ':'; expected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("-0.0Z"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: '-0.0Z'; expected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("-0E123:"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - unexpected ':'; expected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("-0e0-:"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-:'; expected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("-0e-:"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '-0e-:'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("-0f"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: '-0f'; expected end of input",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -894,120 +1041,222 @@ TEST_CASE("parser class")
|
|||||||
SECTION("parse errors")
|
SECTION("parse errors")
|
||||||
{
|
{
|
||||||
// unexpected end of number
|
// unexpected end of number
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("0."),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '0.'", json::parse_error&);
|
parser_helper("0."),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-"),
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '0.'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("--"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '--'", json::parse_error&);
|
parser_helper("-"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-0."),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected digit after '.'; last read: '-0.'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-."),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-.'", json::parse_error&);
|
parser_helper("--"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("-:"),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '--'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-:'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("0.:"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '0.:'", json::parse_error&);
|
parser_helper("-0."),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("e."),
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid number; expected digit after '.'; last read: '-0.'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'e'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("1e."),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e.'", json::parse_error&);
|
parser_helper("-."),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("1e/"),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-.'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e/'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("1e:"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e:'", json::parse_error&);
|
parser_helper("-:"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("1E."),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid number; expected digit after '-'; last read: '-:'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E.'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("1E/"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E/'", json::parse_error&);
|
parser_helper("0.:"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("1E:"),
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected digit after '.'; last read: '0.:'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E:'", json::parse_error&);
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("e."),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'e'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("1e."),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e.'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("1e/"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e/'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("1e:"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1e:'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("1E."),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E.'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("1E/"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E/'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("1E:"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E:'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// unexpected end of null
|
// unexpected end of null
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("n"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 'n'", json::parse_error&);
|
parser_helper("n"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("nu"),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 'n'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'nu'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("nul"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nul'", json::parse_error&);
|
parser_helper("nu"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("nulk"),
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'nu'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nulk'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("nulm"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nulm'", json::parse_error&);
|
parser_helper("nul"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nul'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("nulk"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nulk'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("nulm"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'nulm'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// unexpected end of true
|
// unexpected end of true
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("t"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 't'", json::parse_error&);
|
parser_helper("t"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("tr"),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 't'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'tr'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("tru"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'tru'", json::parse_error&);
|
parser_helper("tr"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("trud"),
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'tr'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'trud'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("truf"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'truf'", json::parse_error&);
|
parser_helper("tru"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'tru'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("trud"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'trud'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("truf"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'truf'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// unexpected end of false
|
// unexpected end of false
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("f"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 'f'", json::parse_error&);
|
parser_helper("f"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("fa"),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid literal; last read: 'f'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'fa'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("fal"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'fal'", json::parse_error&);
|
parser_helper("fa"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("fals"),
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'fa'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'fals'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("falsd"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'falsd'", json::parse_error&);
|
parser_helper("fal"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("falsf"),
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid literal; last read: 'fal'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'falsf'", json::parse_error&);
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("fals"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'fals'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("falsd"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'falsd'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("falsf"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: 'falsf'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// missing/unexpected end of array
|
// missing/unexpected end of array
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("["),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
|
parser_helper("["),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("[1"),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("[1,"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
|
parser_helper("[1"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("[1,]"),
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing array - unexpected end of input; expected ']'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("]"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal", json::parse_error&);
|
parser_helper("[1,"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("[1,]"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("]"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// missing/unexpected end of object
|
// missing/unexpected end of object
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("{"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing object key - unexpected end of input; expected string literal", json::parse_error&);
|
parser_helper("{"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("{\"foo\""),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing object key - unexpected end of input; expected string literal",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing object separator - unexpected end of input; expected ':'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("{\"foo\":"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
|
parser_helper("{\"foo\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("{\"foo\":}"),
|
"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing object separator - unexpected end of input; expected ':'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected '}'; expected '[', '{', or a literal", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("{\"foo\":1,}"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 10: syntax error while parsing object key - unexpected '}'; expected string literal", json::parse_error&);
|
parser_helper("{\"foo\":"),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("}"),
|
"[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected '}'; expected '[', '{', or a literal", json::parse_error&);
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("{\"foo\":}"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected '}'; expected '[', '{', or a literal",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("{\"foo\":1,}"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 10: syntax error while parsing object key - unexpected '}'; expected string literal",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("}"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected '}'; expected '[', '{', or a literal",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// missing/unexpected end of string
|
// missing/unexpected end of string
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\""),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '\"'", json::parse_error&);
|
parser_helper("\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\\\""),
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '\"'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: missing closing quote; last read: '\"\\\"'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\\u\""),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u\"'", json::parse_error&);
|
parser_helper("\"\\\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\\u0\""),
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: missing closing quote; last read: '\"\\\"'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0\"'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\\u01\""),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01\"'", json::parse_error&);
|
parser_helper("\"\\u\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\\u012\""),
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u\"'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012\"'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\\u"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u'", json::parse_error&);
|
parser_helper("\"\\u0\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\\u0"),
|
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0\"'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\\u01"),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01'", json::parse_error&);
|
parser_helper("\"\\u01\""),
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("\"\\u012"),
|
"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01\"'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012'", json::parse_error&);
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\\u012\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012\"'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\\u"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\\u0"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\\u01"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("\"\\u012"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// invalid escapes
|
// invalid escapes
|
||||||
for (int c = 1; c < 128; ++c)
|
for (int c = 1; c < 128; ++c)
|
||||||
@@ -1043,8 +1292,10 @@ TEST_CASE("parser class")
|
|||||||
// only check error message if c is not a control character
|
// only check error message if c is not a control character
|
||||||
if (c > 0x1f)
|
if (c > 0x1f)
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_STD_STR(parser_helper(s),
|
CHECK_THROWS_WITH_STD_STR(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid string: forbidden character after backslash; last read: '\"\\" + std::string(1, static_cast<char>(c)) + "'");
|
parser_helper(s),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid string: forbidden character after backslash; last read: '\"\\" +
|
||||||
|
std::string(1, static_cast<char>(c)) + "'");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1054,8 +1305,7 @@ TEST_CASE("parser class")
|
|||||||
// invalid \uxxxx escapes
|
// invalid \uxxxx escapes
|
||||||
{
|
{
|
||||||
// check whether character is a valid hex character
|
// check whether character is a valid hex character
|
||||||
const auto valid = [](int c)
|
const auto valid = [](int c) {
|
||||||
{
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case ('0'):
|
case ('0'):
|
||||||
@@ -1119,8 +1369,10 @@ TEST_CASE("parser class")
|
|||||||
// only check error message if c is not a control character
|
// only check error message if c is not a control character
|
||||||
if (c > 0x1f)
|
if (c > 0x1f)
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_STD_STR(parser_helper(s1),
|
CHECK_THROWS_WITH_STD_STR(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s1.substr(0, 7) + "'");
|
parser_helper(s1),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" +
|
||||||
|
s1.substr(0, 7) + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
CAPTURE(s2)
|
CAPTURE(s2)
|
||||||
@@ -1128,8 +1380,10 @@ TEST_CASE("parser class")
|
|||||||
// only check error message if c is not a control character
|
// only check error message if c is not a control character
|
||||||
if (c > 0x1f)
|
if (c > 0x1f)
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_STD_STR(parser_helper(s2),
|
CHECK_THROWS_WITH_STD_STR(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s2.substr(0, 6) + "'");
|
parser_helper(s2),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" +
|
||||||
|
s2.substr(0, 6) + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
CAPTURE(s3)
|
CAPTURE(s3)
|
||||||
@@ -1137,8 +1391,10 @@ TEST_CASE("parser class")
|
|||||||
// only check error message if c is not a control character
|
// only check error message if c is not a control character
|
||||||
if (c > 0x1f)
|
if (c > 0x1f)
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_STD_STR(parser_helper(s3),
|
CHECK_THROWS_WITH_STD_STR(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s3.substr(0, 5) + "'");
|
parser_helper(s3),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" +
|
||||||
|
s3.substr(0, 5) + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
CAPTURE(s4)
|
CAPTURE(s4)
|
||||||
@@ -1146,8 +1402,10 @@ TEST_CASE("parser class")
|
|||||||
// only check error message if c is not a control character
|
// only check error message if c is not a control character
|
||||||
if (c > 0x1f)
|
if (c > 0x1f)
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_STD_STR(parser_helper(s4),
|
CHECK_THROWS_WITH_STD_STR(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s4.substr(0, 4) + "'");
|
parser_helper(s4),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '" +
|
||||||
|
s4.substr(0, 4) + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1156,14 +1414,23 @@ TEST_CASE("parser class")
|
|||||||
json _;
|
json _;
|
||||||
|
|
||||||
// missing part of a surrogate pair
|
// missing part of a surrogate pair
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\uD80C\""), "[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\"'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse("\"\\uD80C\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\"'",
|
||||||
|
json::parse_error&);
|
||||||
// invalid surrogate pair
|
// invalid surrogate pair
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\uD80C\\uD80C\""),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uD80C'", json::parse_error&);
|
_ = json::parse("\"\\uD80C\\uD80C\""),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\uD80C\\u0000\""),
|
"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uD80C'",
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\u0000'", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\uD80C\\uFFFF\""),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uFFFF'", json::parse_error&);
|
_ = json::parse("\"\\uD80C\\u0000\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\u0000'",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse("\"\\uD80C\\uFFFF\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uFFFF'",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("parse errors (accept)")
|
SECTION("parse errors (accept)")
|
||||||
@@ -1269,8 +1536,7 @@ TEST_CASE("parser class")
|
|||||||
// invalid \uxxxx escapes
|
// invalid \uxxxx escapes
|
||||||
{
|
{
|
||||||
// check whether character is a valid hex character
|
// check whether character is a valid hex character
|
||||||
const auto valid = [](int c)
|
const auto valid = [](int c) {
|
||||||
{
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case ('0'):
|
case ('0'):
|
||||||
@@ -1355,14 +1621,19 @@ TEST_CASE("parser class")
|
|||||||
SECTION("tests found by mutate++")
|
SECTION("tests found by mutate++")
|
||||||
{
|
{
|
||||||
// test case to make sure no comma precedes the first key
|
// test case to make sure no comma precedes the first key
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("{,\"key\": false}"), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing object key - unexpected ','; expected string literal", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("{,\"key\": false}"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing object key - unexpected ','; expected string literal",
|
||||||
|
json::parse_error&);
|
||||||
// test case to make sure an object is properly closed
|
// test case to make sure an object is properly closed
|
||||||
CHECK_THROWS_WITH_AS(parser_helper("[{\"key\": false true]"), "[json.exception.parse_error.101] parse error at line 1, column 19: syntax error while parsing object - unexpected true literal; expected '}'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
parser_helper("[{\"key\": false true]"),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 19: syntax error while parsing object - unexpected true literal; expected '}'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// test case to make sure the callback is properly evaluated after reading a key
|
// test case to make sure the callback is properly evaluated after reading a key
|
||||||
{
|
{
|
||||||
json::parser_callback_t const cb = [](int /*unused*/, json::parse_event_t event, json& /*unused*/) noexcept
|
json::parser_callback_t const cb = [](int /*unused*/, json::parse_event_t event, json& /*unused*/) noexcept {
|
||||||
{
|
|
||||||
return event != json::parse_event_t::key;
|
return event != json::parse_event_t::key;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1400,15 +1671,13 @@ TEST_CASE("parser class")
|
|||||||
|
|
||||||
SECTION("filter nothing")
|
SECTION("filter nothing")
|
||||||
{
|
{
|
||||||
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
|
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
CHECK(j_object == json({ { "foo", 2 }, { "bar", { { "baz", 1 } } } }));
|
CHECK(j_object == json({ { "foo", 2 }, { "bar", { { "baz", 1 } } } }));
|
||||||
|
|
||||||
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
|
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1417,16 +1686,14 @@ TEST_CASE("parser class")
|
|||||||
|
|
||||||
SECTION("filter everything")
|
SECTION("filter everything")
|
||||||
{
|
{
|
||||||
json const j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
|
json const j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// the top-level object will be discarded, leaving a null
|
// the top-level object will be discarded, leaving a null
|
||||||
CHECK(j_object.is_null());
|
CHECK(j_object.is_null());
|
||||||
|
|
||||||
json const j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
|
json const j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1436,16 +1703,14 @@ TEST_CASE("parser class")
|
|||||||
|
|
||||||
SECTION("filter specific element")
|
SECTION("filter specific element")
|
||||||
{
|
{
|
||||||
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t event, const json & j) noexcept
|
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t event, const json& j) noexcept {
|
||||||
{
|
|
||||||
// filter all number(2) elements
|
// filter all number(2) elements
|
||||||
return event != json::parse_event_t::value || j != json(2);
|
return event != json::parse_event_t::value || j != json(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
CHECK(j_object == json({ { "bar", { { "baz", 1 } } } }));
|
CHECK(j_object == json({ { "bar", { { "baz", 1 } } } }));
|
||||||
|
|
||||||
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t event, const json & j) noexcept
|
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t event, const json& j) noexcept {
|
||||||
{
|
|
||||||
return event != json::parse_event_t::value || j != json(2);
|
return event != json::parse_event_t::value || j != json(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1454,8 +1719,7 @@ TEST_CASE("parser class")
|
|||||||
|
|
||||||
SECTION("filter object in array")
|
SECTION("filter object in array")
|
||||||
{
|
{
|
||||||
json j_filtered1 = json::parse(structured_array, [](int /*unused*/, json::parse_event_t e, const json & parsed)
|
json j_filtered1 = json::parse(structured_array, [](int /*unused*/, json::parse_event_t e, const json& parsed) {
|
||||||
{
|
|
||||||
return !(e == json::parse_event_t::object_end && parsed.contains("foo"));
|
return !(e == json::parse_event_t::object_end && parsed.contains("foo"));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1463,8 +1727,7 @@ TEST_CASE("parser class")
|
|||||||
CHECK(j_filtered1.size() == 2);
|
CHECK(j_filtered1.size() == 2);
|
||||||
CHECK(j_filtered1 == json({ 1, { { "qux", "baz" } } }));
|
CHECK(j_filtered1 == json({ 1, { { "qux", "baz" } } }));
|
||||||
|
|
||||||
json j_filtered2 = json::parse(structured_array, [](int /*unused*/, json::parse_event_t e, const json& /*parsed*/) noexcept
|
json j_filtered2 = json::parse(structured_array, [](int /*unused*/, json::parse_event_t e, const json& /*parsed*/) noexcept {
|
||||||
{
|
|
||||||
return e != json::parse_event_t::object_end;
|
return e != json::parse_event_t::object_end;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1478,8 +1741,7 @@ TEST_CASE("parser class")
|
|||||||
SECTION("first closing event")
|
SECTION("first closing event")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept
|
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept {
|
||||||
{
|
|
||||||
static bool first = true;
|
static bool first = true;
|
||||||
if (e == json::parse_event_t::object_end && first)
|
if (e == json::parse_event_t::object_end && first)
|
||||||
{
|
{
|
||||||
@@ -1495,8 +1757,7 @@ TEST_CASE("parser class")
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept
|
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept {
|
||||||
{
|
|
||||||
static bool first = true;
|
static bool first = true;
|
||||||
if (e == json::parse_event_t::array_end && first)
|
if (e == json::parse_event_t::array_end && first)
|
||||||
{
|
{
|
||||||
@@ -1519,14 +1780,12 @@ TEST_CASE("parser class")
|
|||||||
// object and array is discarded only after the closing character
|
// object and array is discarded only after the closing character
|
||||||
// has been read
|
// has been read
|
||||||
|
|
||||||
json j_empty_object = json::parse("{}", [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept
|
json j_empty_object = json::parse("{}", [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept {
|
||||||
{
|
|
||||||
return e != json::parse_event_t::object_end;
|
return e != json::parse_event_t::object_end;
|
||||||
});
|
});
|
||||||
CHECK(j_empty_object == json());
|
CHECK(j_empty_object == json());
|
||||||
|
|
||||||
json j_empty_array = json::parse("[]", [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept
|
json j_empty_array = json::parse("[]", [](int /*unused*/, json::parse_event_t e, const json& /*unused*/) noexcept {
|
||||||
{
|
|
||||||
return e != json::parse_event_t::array_end;
|
return e != json::parse_event_t::array_end;
|
||||||
});
|
});
|
||||||
CHECK(j_empty_array == json());
|
CHECK(j_empty_array == json());
|
||||||
@@ -1593,17 +1852,21 @@ TEST_CASE("parser class")
|
|||||||
{
|
{
|
||||||
SECTION("parser with callback")
|
SECTION("parser with callback")
|
||||||
{
|
{
|
||||||
json::parser_callback_t const cb = [](int /*unused*/, json::parse_event_t /*unused*/, json& /*unused*/) noexcept
|
json::parser_callback_t const cb = [](int /*unused*/, json::parse_event_t /*unused*/, json& /*unused*/) noexcept {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
CHECK(json::parse("{\"foo\": true:", cb, false).is_discarded());
|
CHECK(json::parse("{\"foo\": true:", cb, false).is_discarded());
|
||||||
|
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("{\"foo\": true:", cb), "[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing object - unexpected ':'; expected '}'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse("{\"foo\": true:", cb),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing object - unexpected ':'; expected '}'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("1.18973e+4932", cb), "[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(_ = json::parse("1.18973e+4932", cb),
|
||||||
|
"[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'",
|
||||||
|
json::out_of_range&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("SAX parser")
|
SECTION("SAX parser")
|
||||||
@@ -1685,7 +1948,13 @@ TEST_CASE("parser class")
|
|||||||
SECTION("error messages for comments")
|
SECTION("error messages for comments")
|
||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("/a", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid comment; expecting '/' or '*' after '/'; last read: '/a'", json::parse_error);
|
CHECK_THROWS_WITH_AS(
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("/*", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid comment; missing closing '*/'; last read: '/*<U+0000>'", json::parse_error);
|
_ = json::parse("/a", nullptr, true, true),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid comment; expecting '/' or '*' after '/'; last read: '/a'",
|
||||||
|
json::parse_error);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse("/*", nullptr, true, true),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid comment; missing closing '*/'; last read: '/*<U+0000>'",
|
||||||
|
json::parse_error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ using nlohmann::json;
|
|||||||
// this can be replaced with the doctest stl extension header in version 2.5
|
// this can be replaced with the doctest stl extension header in version 2.5
|
||||||
namespace doctest
|
namespace doctest
|
||||||
{
|
{
|
||||||
template<> struct StringMaker<std::partial_ordering>
|
template<>
|
||||||
|
struct StringMaker<std::partial_ordering>
|
||||||
{
|
{
|
||||||
static String convert(const std::partial_ordering& order)
|
static String convert(const std::partial_ordering& order)
|
||||||
{
|
{
|
||||||
@@ -86,22 +87,12 @@ TEST_CASE("lexicographical comparison operators")
|
|||||||
|
|
||||||
SECTION("types")
|
SECTION("types")
|
||||||
{
|
{
|
||||||
std::vector<json::value_t> j_types =
|
std::vector<json::value_t> j_types = {
|
||||||
{
|
json::value_t::null, json::value_t::boolean, json::value_t::number_integer, json::value_t::number_unsigned, json::value_t::number_float,
|
||||||
json::value_t::null,
|
json::value_t::object, json::value_t::array, json::value_t::string, json::value_t::binary, json::value_t::discarded
|
||||||
json::value_t::boolean,
|
|
||||||
json::value_t::number_integer,
|
|
||||||
json::value_t::number_unsigned,
|
|
||||||
json::value_t::number_float,
|
|
||||||
json::value_t::object,
|
|
||||||
json::value_t::array,
|
|
||||||
json::value_t::string,
|
|
||||||
json::value_t::binary,
|
|
||||||
json::value_t::discarded
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::vector<bool>> expected_lt =
|
std::vector<std::vector<bool>> expected_lt = {
|
||||||
{
|
|
||||||
//0 1 2 3 4 5 6 7 8 9
|
//0 1 2 3 4 5 6 7 8 9
|
||||||
{ f_, _t, _t, _t, _t, _t, _t, _t, _t, f_ }, // 0
|
{ f_, _t, _t, _t, _t, _t, _t, _t, _t, f_ }, // 0
|
||||||
{ f_, f_, _t, _t, _t, _t, _t, _t, _t, f_ }, // 1
|
{ f_, f_, _t, _t, _t, _t, _t, _t, _t, f_ }, // 1
|
||||||
@@ -140,8 +131,7 @@ TEST_CASE("lexicographical comparison operators")
|
|||||||
// JSON_HAS_CPP_20 (do not remove; see note at top of file)
|
// JSON_HAS_CPP_20 (do not remove; see note at top of file)
|
||||||
SECTION("comparison: 3-way")
|
SECTION("comparison: 3-way")
|
||||||
{
|
{
|
||||||
std::vector<std::vector<std::partial_ordering>> expected =
|
std::vector<std::vector<std::partial_ordering>> expected = {
|
||||||
{
|
|
||||||
//0 1 2 3 4 5 6 7 8 9
|
//0 1 2 3 4 5 6 7 8 9
|
||||||
{ eq, lt, lt, lt, lt, lt, lt, lt, lt, un }, // 0
|
{ eq, lt, lt, lt, lt, lt, lt, lt, lt, un }, // 0
|
||||||
{ gt, eq, lt, lt, lt, lt, lt, lt, lt, un }, // 1
|
{ gt, eq, lt, lt, lt, lt, lt, lt, lt, un }, // 1
|
||||||
@@ -186,23 +176,32 @@ TEST_CASE("lexicographical comparison operators")
|
|||||||
|
|
||||||
SECTION("values")
|
SECTION("values")
|
||||||
{
|
{
|
||||||
json j_values =
|
json j_values = {
|
||||||
{
|
nullptr,
|
||||||
nullptr, nullptr, // 0 1
|
nullptr, // 0 1
|
||||||
-17, 42, // 2 3
|
-17,
|
||||||
8u, 13u, // 4 5
|
42, // 2 3
|
||||||
3.14159, 23.42, // 6 7
|
8u,
|
||||||
nan, nan, // 8 9
|
13u, // 4 5
|
||||||
"foo", "bar", // 10 11
|
3.14159,
|
||||||
true, false, // 12 13
|
23.42, // 6 7
|
||||||
{1, 2, 3}, {"one", "two", "three"}, // 14 15
|
nan,
|
||||||
{{"first", 1}, {"second", 2}}, {{"a", "A"}, {"b", {"B"}}}, // 16 17
|
nan, // 8 9
|
||||||
json::binary({1, 2, 3}), json::binary({1, 2, 4}), // 18 19
|
"foo",
|
||||||
json(json::value_t::discarded), json(json::value_t::discarded) // 20 21
|
"bar", // 10 11
|
||||||
|
true,
|
||||||
|
false, // 12 13
|
||||||
|
{ 1, 2, 3 },
|
||||||
|
{ "one", "two", "three" }, // 14 15
|
||||||
|
{ { "first", 1 }, { "second", 2 } },
|
||||||
|
{ { "a", "A" }, { "b", { "B" } } }, // 16 17
|
||||||
|
json::binary({ 1, 2, 3 }),
|
||||||
|
json::binary({ 1, 2, 4 }), // 18 19
|
||||||
|
json(json::value_t::discarded),
|
||||||
|
json(json::value_t::discarded) // 20 21
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::vector<bool>> expected_eq =
|
std::vector<std::vector<bool>> expected_eq = {
|
||||||
{
|
|
||||||
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||||
{ _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_ }, // 0
|
{ _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_ }, // 0
|
||||||
{ _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_ }, // 1
|
{ _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_ }, // 1
|
||||||
@@ -228,8 +227,7 @@ TEST_CASE("lexicographical comparison operators")
|
|||||||
{ f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_ }, // 21
|
{ f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_ }, // 21
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::vector<bool>> expected_lt =
|
std::vector<std::vector<bool>> expected_lt = {
|
||||||
{
|
|
||||||
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||||
{ f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_ }, // 0
|
{ f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_ }, // 0
|
||||||
{ f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_ }, // 1
|
{ f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_ }, // 1
|
||||||
@@ -257,8 +255,7 @@ TEST_CASE("lexicographical comparison operators")
|
|||||||
|
|
||||||
SECTION("compares unordered")
|
SECTION("compares unordered")
|
||||||
{
|
{
|
||||||
std::vector<std::vector<bool>> expected =
|
std::vector<std::vector<bool>> expected = {
|
||||||
{
|
|
||||||
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||||
{ f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t }, // 0
|
{ f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t }, // 0
|
||||||
{ f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t }, // 1
|
{ f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t }, // 1
|
||||||
@@ -301,8 +298,7 @@ TEST_CASE("lexicographical comparison operators")
|
|||||||
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
|
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
|
||||||
SECTION("compares unordered (inverse)")
|
SECTION("compares unordered (inverse)")
|
||||||
{
|
{
|
||||||
std::vector<std::vector<bool>> expected =
|
std::vector<std::vector<bool>> expected = {
|
||||||
{
|
|
||||||
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||||
{ f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_ }, // 0
|
{ f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_ }, // 0
|
||||||
{ f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_ }, // 1
|
{ f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_ }, // 1
|
||||||
@@ -496,8 +492,7 @@ TEST_CASE("lexicographical comparison operators")
|
|||||||
// JSON_HAS_CPP_20 (do not remove; see note at top of file)
|
// JSON_HAS_CPP_20 (do not remove; see note at top of file)
|
||||||
SECTION("comparison: 3-way")
|
SECTION("comparison: 3-way")
|
||||||
{
|
{
|
||||||
std::vector<std::vector<std::partial_ordering>> expected =
|
std::vector<std::vector<std::partial_ordering>> expected = {
|
||||||
{
|
|
||||||
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||||
{ eq, eq, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, un, un }, // 0
|
{ eq, eq, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, un, un }, // 0
|
||||||
{ eq, eq, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, un, un }, // 1
|
{ eq, eq, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, un, un }, // 1
|
||||||
@@ -576,16 +571,14 @@ TEST_CASE("lexicographical comparison operators")
|
|||||||
[1,2,[3,4,5],4,5]
|
[1,2,[3,4,5],4,5]
|
||||||
)";
|
)";
|
||||||
|
|
||||||
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json & j) noexcept
|
json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json& j) noexcept {
|
||||||
{
|
|
||||||
// filter all number(2) elements
|
// filter all number(2) elements
|
||||||
return j != json(2);
|
return j != json(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
CHECK(j_object == json({ { "bar", { { "baz", 1 } } } }));
|
CHECK(j_object == json({ { "bar", { { "baz", 1 } } } }));
|
||||||
|
|
||||||
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json & j) noexcept
|
json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json& j) noexcept {
|
||||||
{
|
|
||||||
return j != json(2);
|
return j != json(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,7 @@ TEST_CASE("concepts")
|
|||||||
// X::size_type must return an unsigned integer
|
// X::size_type must return an unsigned integer
|
||||||
CHECK((std::is_unsigned<json::size_type>::value));
|
CHECK((std::is_unsigned<json::size_type>::value));
|
||||||
// X::size_type can represent any non-negative value of X::difference_type
|
// X::size_type can represent any non-negative value of X::difference_type
|
||||||
CHECK(static_cast<json::size_type>((std::numeric_limits<json::difference_type>::max)()) <=
|
CHECK(static_cast<json::size_type>((std::numeric_limits<json::difference_type>::max)()) <= (std::numeric_limits<json::size_type>::max)());
|
||||||
(std::numeric_limits<json::size_type>::max)());
|
|
||||||
|
|
||||||
// the expression "X u" has the post-condition "u.empty()"
|
// the expression "X u" has the post-condition "u.empty()"
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -140,12 +140,14 @@ TEST_CASE("constructors")
|
|||||||
SECTION("create an object (implicit)")
|
SECTION("create an object (implicit)")
|
||||||
{
|
{
|
||||||
// reference object
|
// reference object
|
||||||
json::object_t const o_reference {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
|
json::object_t const o_reference{ { "a", json(1) }, { "b", json(1u) }, { "c", json(2.2) },
|
||||||
|
{ "d", json(false) }, { "e", json("string") }, { "f", json() } };
|
||||||
json const j_reference(o_reference);
|
json const j_reference(o_reference);
|
||||||
|
|
||||||
SECTION("std::map<json::string_t, json>")
|
SECTION("std::map<json::string_t, json>")
|
||||||
{
|
{
|
||||||
std::map<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
|
std::map<json::string_t, json> const o{ { "a", json(1) }, { "b", json(1u) }, { "c", json(2.2) },
|
||||||
|
{ "d", json(false) }, { "e", json("string") }, { "f", json() } };
|
||||||
json const j(o);
|
json const j(o);
|
||||||
CHECK(j.type() == json::value_t::object);
|
CHECK(j.type() == json::value_t::object);
|
||||||
CHECK(j == j_reference);
|
CHECK(j == j_reference);
|
||||||
@@ -153,8 +155,7 @@ TEST_CASE("constructors")
|
|||||||
|
|
||||||
SECTION("std::map<std::string, std::string> #600")
|
SECTION("std::map<std::string, std::string> #600")
|
||||||
{
|
{
|
||||||
const std::map<std::string, std::string> m
|
const std::map<std::string, std::string> m{
|
||||||
{
|
|
||||||
{ "a", "b" },
|
{ "a", "b" },
|
||||||
{ "c", "d" },
|
{ "c", "d" },
|
||||||
{ "e", "f" },
|
{ "e", "f" },
|
||||||
@@ -166,7 +167,8 @@ TEST_CASE("constructors")
|
|||||||
|
|
||||||
SECTION("std::map<const char*, json>")
|
SECTION("std::map<const char*, json>")
|
||||||
{
|
{
|
||||||
std::map<const char*, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
|
std::map<const char*, json> const o{ { "a", json(1) }, { "b", json(1u) }, { "c", json(2.2) },
|
||||||
|
{ "d", json(false) }, { "e", json("string") }, { "f", json() } };
|
||||||
json const j(o);
|
json const j(o);
|
||||||
CHECK(j.type() == json::value_t::object);
|
CHECK(j.type() == json::value_t::object);
|
||||||
CHECK(j == j_reference);
|
CHECK(j == j_reference);
|
||||||
@@ -174,7 +176,8 @@ TEST_CASE("constructors")
|
|||||||
|
|
||||||
SECTION("std::multimap<json::string_t, json>")
|
SECTION("std::multimap<json::string_t, json>")
|
||||||
{
|
{
|
||||||
std::multimap<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
|
std::multimap<json::string_t, json> const o{ { "a", json(1) }, { "b", json(1u) }, { "c", json(2.2) },
|
||||||
|
{ "d", json(false) }, { "e", json("string") }, { "f", json() } };
|
||||||
json const j(o);
|
json const j(o);
|
||||||
CHECK(j.type() == json::value_t::object);
|
CHECK(j.type() == json::value_t::object);
|
||||||
CHECK(j == j_reference);
|
CHECK(j == j_reference);
|
||||||
@@ -182,7 +185,8 @@ TEST_CASE("constructors")
|
|||||||
|
|
||||||
SECTION("std::unordered_map<json::string_t, json>")
|
SECTION("std::unordered_map<json::string_t, json>")
|
||||||
{
|
{
|
||||||
std::unordered_map<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
|
std::unordered_map<json::string_t, json> const o{ { "a", json(1) }, { "b", json(1u) }, { "c", json(2.2) },
|
||||||
|
{ "d", json(false) }, { "e", json("string") }, { "f", json() } };
|
||||||
json const j(o);
|
json const j(o);
|
||||||
CHECK(j.type() == json::value_t::object);
|
CHECK(j.type() == json::value_t::object);
|
||||||
CHECK(j == j_reference);
|
CHECK(j == j_reference);
|
||||||
@@ -190,7 +194,8 @@ TEST_CASE("constructors")
|
|||||||
|
|
||||||
SECTION("std::unordered_multimap<json::string_t, json>")
|
SECTION("std::unordered_multimap<json::string_t, json>")
|
||||||
{
|
{
|
||||||
std::unordered_multimap<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
|
std::unordered_multimap<json::string_t, json> const o{ { "a", json(1) }, { "b", json(1u) }, { "c", json(2.2) },
|
||||||
|
{ "d", json(false) }, { "e", json("string") }, { "f", json() } };
|
||||||
json const j(o);
|
json const j(o);
|
||||||
CHECK(j.type() == json::value_t::object);
|
CHECK(j.type() == json::value_t::object);
|
||||||
CHECK(j == j_reference);
|
CHECK(j == j_reference);
|
||||||
@@ -1084,7 +1089,9 @@ TEST_CASE("constructors")
|
|||||||
SECTION("object with error")
|
SECTION("object with error")
|
||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }), "[json.exception.type_error.301] cannot create object from initializer list", json::type_error&);
|
CHECK_THROWS_WITH_AS(_ = json::object({ { "one", 1 }, { "two", 1u }, { "three", 2.2 }, { "four", false }, 13 }),
|
||||||
|
"[json.exception.type_error.301] cannot create object from initializer list",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("empty array")
|
SECTION("empty array")
|
||||||
@@ -1250,7 +1257,6 @@ TEST_CASE("constructors")
|
|||||||
CHECK(&j["key"][0] == source_addr);
|
CHECK(&j["key"][0] == source_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1330,14 +1336,22 @@ TEST_CASE("constructors")
|
|||||||
{
|
{
|
||||||
json jobject = { { "a", "a" }, { "b", 1 }, { "c", 17u }, { "d", false }, { "e", true } };
|
json jobject = { { "a", "a" }, { "b", 1 }, { "c", 17u }, { "d", false }, { "e", true } };
|
||||||
json jobject2 = { { "a", "a" }, { "b", 1 }, { "c", 17u } };
|
json jobject2 = { { "a", "a" }, { "b", 1 }, { "c", 17u } };
|
||||||
CHECK_THROWS_WITH_AS(json(jobject.begin(), jobject2.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(jobject.begin(), jobject2.end()),
|
||||||
CHECK_THROWS_WITH_AS(json(jobject2.begin(), jobject.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.201] iterators are not compatible",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(json(jobject2.begin(), jobject.end()),
|
||||||
|
"[json.exception.invalid_iterator.201] iterators are not compatible",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json const jobject = { { "a", "a" }, { "b", 1 }, { "c", 17u }, { "d", false }, { "e", true } };
|
json const jobject = { { "a", "a" }, { "b", 1 }, { "c", 17u }, { "d", false }, { "e", true } };
|
||||||
json const jobject2 = { { "a", "a" }, { "b", 1 }, { "c", 17u } };
|
json const jobject2 = { { "a", "a" }, { "b", 1 }, { "c", 17u } };
|
||||||
CHECK_THROWS_WITH_AS(json(jobject.cbegin(), jobject2.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(jobject.cbegin(), jobject2.cend()),
|
||||||
CHECK_THROWS_WITH_AS(json(jobject2.cbegin(), jobject.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.201] iterators are not compatible",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(json(jobject2.cbegin(), jobject.cend()),
|
||||||
|
"[json.exception.invalid_iterator.201] iterators are not compatible",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1391,14 +1405,22 @@ TEST_CASE("constructors")
|
|||||||
{
|
{
|
||||||
json jarray = { 1, 2, 3, 4 };
|
json jarray = { 1, 2, 3, 4 };
|
||||||
json jarray2 = { 2, 3, 4, 5 };
|
json jarray2 = { 2, 3, 4, 5 };
|
||||||
CHECK_THROWS_WITH_AS(json(jarray.begin(), jarray2.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(jarray.begin(), jarray2.end()),
|
||||||
CHECK_THROWS_WITH_AS(json(jarray2.begin(), jarray.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.201] iterators are not compatible",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(json(jarray2.begin(), jarray.end()),
|
||||||
|
"[json.exception.invalid_iterator.201] iterators are not compatible",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json const jarray = { 1, 2, 3, 4 };
|
json const jarray = { 1, 2, 3, 4 };
|
||||||
json const jarray2 = { 2, 3, 4, 5 };
|
json const jarray2 = { 2, 3, 4, 5 };
|
||||||
CHECK_THROWS_WITH_AS(json(jarray.cbegin(), jarray2.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(jarray.cbegin(), jarray2.cend()),
|
||||||
CHECK_THROWS_WITH_AS(json(jarray2.cbegin(), jarray.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.201] iterators are not compatible",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(json(jarray2.cbegin(), jarray.cend()),
|
||||||
|
"[json.exception.invalid_iterator.201] iterators are not compatible",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1411,11 +1433,15 @@ TEST_CASE("constructors")
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
json j;
|
json j;
|
||||||
CHECK_THROWS_WITH_AS(json(j.begin(), j.end()), "[json.exception.invalid_iterator.206] cannot construct with iterators from null", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.begin(), j.end()),
|
||||||
|
"[json.exception.invalid_iterator.206] cannot construct with iterators from null",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json const j;
|
json const j;
|
||||||
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cend()), "[json.exception.invalid_iterator.206] cannot construct with iterators from null", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cend()),
|
||||||
|
"[json.exception.invalid_iterator.206] cannot construct with iterators from null",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1511,12 +1537,16 @@ TEST_CASE("constructors")
|
|||||||
{
|
{
|
||||||
json j = "foo";
|
json j = "foo";
|
||||||
CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json const j = "bar";
|
json const j = "bar";
|
||||||
CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1525,12 +1555,16 @@ TEST_CASE("constructors")
|
|||||||
{
|
{
|
||||||
json j = false;
|
json j = false;
|
||||||
CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json const j = true;
|
json const j = true;
|
||||||
CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1539,12 +1573,16 @@ TEST_CASE("constructors")
|
|||||||
{
|
{
|
||||||
json j = 17;
|
json j = 17;
|
||||||
CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json const j = 17;
|
json const j = 17;
|
||||||
CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1553,12 +1591,16 @@ TEST_CASE("constructors")
|
|||||||
{
|
{
|
||||||
json j = 17u;
|
json j = 17u;
|
||||||
CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json const j = 17u;
|
json const j = 17u;
|
||||||
CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1567,12 +1609,16 @@ TEST_CASE("constructors")
|
|||||||
{
|
{
|
||||||
json j = 23.42;
|
json j = 23.42;
|
||||||
CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json const j = 23.42;
|
json const j = 23.42;
|
||||||
CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+224
-265
@@ -36,13 +36,8 @@ TEST_CASE("value conversion")
|
|||||||
{
|
{
|
||||||
SECTION("get an object (explicit)")
|
SECTION("get an object (explicit)")
|
||||||
{
|
{
|
||||||
const json::object_t o_reference = {{"object", json::object()},
|
const json::object_t o_reference = { { "object", json::object() }, { "array", { 1, 2, 3, 4 } }, { "number", 42 },
|
||||||
{"array", {1, 2, 3, 4}},
|
{ "boolean", false }, { "null", nullptr }, { "string", "Hello world" } };
|
||||||
{"number", 42},
|
|
||||||
{"boolean", false},
|
|
||||||
{"null", nullptr},
|
|
||||||
{"string", "Hello world"}
|
|
||||||
};
|
|
||||||
json j(o_reference);
|
json j(o_reference);
|
||||||
|
|
||||||
SECTION("json::object_t")
|
SECTION("json::object_t")
|
||||||
@@ -53,67 +48,59 @@ TEST_CASE("value conversion")
|
|||||||
|
|
||||||
SECTION("std::map<json::string_t, json>")
|
SECTION("std::map<json::string_t, json>")
|
||||||
{
|
{
|
||||||
const std::map<json::string_t, json> o =
|
const std::map<json::string_t, json> o = j.get<std::map<json::string_t, json>>();
|
||||||
j.get<std::map<json::string_t, json>>();
|
|
||||||
CHECK(json(o) == j);
|
CHECK(json(o) == j);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("std::multimap<json::string_t, json>")
|
SECTION("std::multimap<json::string_t, json>")
|
||||||
{
|
{
|
||||||
const std::multimap<json::string_t, json> o =
|
const std::multimap<json::string_t, json> o = j.get<std::multimap<json::string_t, json>>();
|
||||||
j.get<std::multimap<json::string_t, json>>();
|
|
||||||
CHECK(json(o) == j);
|
CHECK(json(o) == j);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("std::unordered_map<json::string_t, json>")
|
SECTION("std::unordered_map<json::string_t, json>")
|
||||||
{
|
{
|
||||||
const std::unordered_map<json::string_t, json> o =
|
const std::unordered_map<json::string_t, json> o = j.get<std::unordered_map<json::string_t, json>>();
|
||||||
j.get<std::unordered_map<json::string_t, json>>();
|
|
||||||
CHECK(json(o) == j);
|
CHECK(json(o) == j);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("std::unordered_multimap<json::string_t, json>")
|
SECTION("std::unordered_multimap<json::string_t, json>")
|
||||||
{
|
{
|
||||||
const std::unordered_multimap<json::string_t, json> o =
|
const std::unordered_multimap<json::string_t, json> o = j.get<std::unordered_multimap<json::string_t, json>>();
|
||||||
j.get<std::unordered_multimap<json::string_t, json>>();
|
|
||||||
CHECK(json(o) == j);
|
CHECK(json(o) == j);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("exception in case of a non-object type")
|
SECTION("exception in case of a non-object type")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::null).get<json::object_t>(),
|
||||||
json(json::value_t::null).get<json::object_t>(),
|
"[json.exception.type_error.302] type must be object, but is null",
|
||||||
"[json.exception.type_error.302] type must be object, but is null", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::array).get<json::object_t>(),
|
||||||
json(json::value_t::array).get<json::object_t>(),
|
"[json.exception.type_error.302] type must be object, but is array",
|
||||||
"[json.exception.type_error.302] type must be object, but is array", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::string).get<json::object_t>(),
|
||||||
json(json::value_t::string).get<json::object_t>(),
|
"[json.exception.type_error.302] type must be object, but is string",
|
||||||
"[json.exception.type_error.302] type must be object, but is string", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<json::object_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<json::object_t>(),
|
||||||
"[json.exception.type_error.302] type must be object, "
|
"[json.exception.type_error.302] type must be object, "
|
||||||
"but is boolean", json::type_error&);
|
"but is boolean",
|
||||||
CHECK_THROWS_WITH_AS(
|
json::type_error&);
|
||||||
json(json::value_t::number_integer).get<json::object_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_integer).get<json::object_t>(),
|
||||||
"[json.exception.type_error.302] type must be object, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be object, but is number",
|
||||||
CHECK_THROWS_WITH_AS(
|
json::type_error&);
|
||||||
json(json::value_t::number_unsigned).get<json::object_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_unsigned).get<json::object_t>(),
|
||||||
"[json.exception.type_error.302] type must be object, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be object, but is number",
|
||||||
CHECK_THROWS_WITH_AS(
|
json::type_error&);
|
||||||
json(json::value_t::number_float).get<json::object_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_float).get<json::object_t>(),
|
||||||
"[json.exception.type_error.302] type must be object, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be object, but is number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("get an object (explicit, get_to)")
|
SECTION("get an object (explicit, get_to)")
|
||||||
{
|
{
|
||||||
const json::object_t o_reference = {{"object", json::object()},
|
const json::object_t o_reference = { { "object", json::object() }, { "array", { 1, 2, 3, 4 } }, { "number", 42 },
|
||||||
{"array", {1, 2, 3, 4}},
|
{ "boolean", false }, { "null", nullptr }, { "string", "Hello world" } };
|
||||||
{"number", 42},
|
|
||||||
{"boolean", false},
|
|
||||||
{"null", nullptr},
|
|
||||||
{"string", "Hello world"}
|
|
||||||
};
|
|
||||||
json j(o_reference);
|
json j(o_reference);
|
||||||
|
|
||||||
SECTION("json::object_t")
|
SECTION("json::object_t")
|
||||||
@@ -155,13 +142,8 @@ TEST_CASE("value conversion")
|
|||||||
#if JSON_USE_IMPLICIT_CONVERSIONS
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
SECTION("get an object (implicit)")
|
SECTION("get an object (implicit)")
|
||||||
{
|
{
|
||||||
const json::object_t o_reference = {{"object", json::object()},
|
const json::object_t o_reference = { { "object", json::object() }, { "array", { 1, 2, 3, 4 } }, { "number", 42 },
|
||||||
{"array", {1, 2, 3, 4}},
|
{ "boolean", false }, { "null", nullptr }, { "string", "Hello world" } };
|
||||||
{"number", 42},
|
|
||||||
{"boolean", false},
|
|
||||||
{"null", nullptr},
|
|
||||||
{"string", "Hello world"}
|
|
||||||
};
|
|
||||||
json j(o_reference);
|
json j(o_reference);
|
||||||
|
|
||||||
SECTION("json::object_t")
|
SECTION("json::object_t")
|
||||||
@@ -198,8 +180,7 @@ TEST_CASE("value conversion")
|
|||||||
|
|
||||||
SECTION("get an array (explicit)")
|
SECTION("get an array (explicit)")
|
||||||
{
|
{
|
||||||
const json::array_t a_reference{json(1), json(1u), json(2.2),
|
const json::array_t a_reference{ json(1), json(1u), json(2.2), json(false), json("string"), json() };
|
||||||
json(false), json("string"), json()};
|
|
||||||
json j(a_reference);
|
json j(a_reference);
|
||||||
|
|
||||||
SECTION("json::array_t")
|
SECTION("json::array_t")
|
||||||
@@ -219,9 +200,9 @@ TEST_CASE("value conversion")
|
|||||||
const std::forward_list<json> a = j.get<std::forward_list<json>>();
|
const std::forward_list<json> a = j.get<std::forward_list<json>>();
|
||||||
CHECK(json(a) == j);
|
CHECK(json(a) == j);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::null).get<std::forward_list<json>>(),
|
||||||
json(json::value_t::null).get<std::forward_list<json>>(),
|
"[json.exception.type_error.302] type must be array, but is null",
|
||||||
"[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("std::vector<json>")
|
SECTION("std::vector<json>")
|
||||||
@@ -229,9 +210,9 @@ TEST_CASE("value conversion")
|
|||||||
const std::vector<json> a = j.get<std::vector<json>>();
|
const std::vector<json> a = j.get<std::vector<json>>();
|
||||||
CHECK(json(a) == j);
|
CHECK(json(a) == j);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::null).get<std::vector<json>>(),
|
||||||
json(json::value_t::null).get<std::vector<json>>(),
|
"[json.exception.type_error.302] type must be array, but is null",
|
||||||
"[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
json::type_error&);
|
||||||
|
|
||||||
#if !defined(JSON_NOEXCEPTION)
|
#if !defined(JSON_NOEXCEPTION)
|
||||||
SECTION("reserve is called on containers that supports it")
|
SECTION("reserve is called on containers that supports it")
|
||||||
@@ -266,37 +247,36 @@ TEST_CASE("value conversion")
|
|||||||
|
|
||||||
SECTION("exception in case of a non-array type")
|
SECTION("exception in case of a non-array type")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<std::vector<int>>(),
|
||||||
json(json::value_t::object).get<std::vector<int>>(),
|
"[json.exception.type_error.302] type must be array, but is object",
|
||||||
"[json.exception.type_error.302] type must be array, but is object", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::null).get<json::array_t>(),
|
||||||
json(json::value_t::null).get<json::array_t>(),
|
"[json.exception.type_error.302] type must be array, but is null",
|
||||||
"[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<json::array_t>(),
|
||||||
json(json::value_t::object).get<json::array_t>(),
|
"[json.exception.type_error.302] type must be array, but is object",
|
||||||
"[json.exception.type_error.302] type must be array, but is object", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::string).get<json::array_t>(),
|
||||||
json(json::value_t::string).get<json::array_t>(),
|
"[json.exception.type_error.302] type must be array, but is string",
|
||||||
"[json.exception.type_error.302] type must be array, but is string", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<json::array_t>(),
|
||||||
json(json::value_t::boolean).get<json::array_t>(),
|
"[json.exception.type_error.302] type must be array, but is boolean",
|
||||||
"[json.exception.type_error.302] type must be array, but is boolean", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_integer).get<json::array_t>(),
|
||||||
json(json::value_t::number_integer).get<json::array_t>(),
|
"[json.exception.type_error.302] type must be array, but is number",
|
||||||
"[json.exception.type_error.302] type must be array, but is number", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_unsigned).get<json::array_t>(),
|
||||||
json(json::value_t::number_unsigned).get<json::array_t>(),
|
"[json.exception.type_error.302] type must be array, but is number",
|
||||||
"[json.exception.type_error.302] type must be array, but is number", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_float).get<json::array_t>(),
|
||||||
json(json::value_t::number_float).get<json::array_t>(),
|
"[json.exception.type_error.302] type must be array, but is number",
|
||||||
"[json.exception.type_error.302] type must be array, but is number", json::type_error&);
|
json::type_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("get an array (explicit, get_to)")
|
SECTION("get an array (explicit, get_to)")
|
||||||
{
|
{
|
||||||
const json::array_t a_reference{json(1), json(1u), json(2.2),
|
const json::array_t a_reference{ json(1), json(1u), json(2.2), json(false), json("string"), json() };
|
||||||
json(false), json("string"), json()};
|
|
||||||
json j(a_reference);
|
json j(a_reference);
|
||||||
|
|
||||||
SECTION("json::array_t")
|
SECTION("json::array_t")
|
||||||
@@ -355,8 +335,7 @@ TEST_CASE("value conversion")
|
|||||||
#if JSON_USE_IMPLICIT_CONVERSIONS
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
SECTION("get an array (implicit)")
|
SECTION("get an array (implicit)")
|
||||||
{
|
{
|
||||||
const json::array_t a_reference{json(1), json(1u), json(2.2),
|
const json::array_t a_reference{ json(1), json(1u), json(2.2), json(false), json("string"), json() };
|
||||||
json(false), json("string"), json()};
|
|
||||||
json j(a_reference);
|
json j(a_reference);
|
||||||
|
|
||||||
SECTION("json::array_t")
|
SECTION("json::array_t")
|
||||||
@@ -417,46 +396,54 @@ TEST_CASE("value conversion")
|
|||||||
|
|
||||||
SECTION("exception in case of a non-string type")
|
SECTION("exception in case of a non-string type")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::null).get<json::string_t>(),
|
||||||
json(json::value_t::null).get<json::string_t>(),
|
"[json.exception.type_error.302] type must be string, but is null",
|
||||||
"[json.exception.type_error.302] type must be string, but is null", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<json::string_t>(),
|
||||||
json(json::value_t::object).get<json::string_t>(),
|
"[json.exception.type_error.302] type must be string, but is object",
|
||||||
"[json.exception.type_error.302] type must be string, but is object", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::array).get<json::string_t>(),
|
||||||
json(json::value_t::array).get<json::string_t>(),
|
"[json.exception.type_error.302] type must be string, but is array",
|
||||||
"[json.exception.type_error.302] type must be string, but is array", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<json::string_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<json::string_t>(),
|
||||||
"[json.exception.type_error.302] type must be string, "
|
"[json.exception.type_error.302] type must be string, "
|
||||||
"but is boolean", json::type_error&);
|
"but is boolean",
|
||||||
CHECK_THROWS_WITH_AS(
|
json::type_error&);
|
||||||
json(json::value_t::number_integer).get<json::string_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_integer).get<json::string_t>(),
|
||||||
"[json.exception.type_error.302] type must be string, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be string, but is number",
|
||||||
CHECK_THROWS_WITH_AS(
|
json::type_error&);
|
||||||
json(json::value_t::number_unsigned).get<json::string_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_unsigned).get<json::string_t>(),
|
||||||
"[json.exception.type_error.302] type must be string, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be string, but is number",
|
||||||
CHECK_THROWS_WITH_AS(
|
json::type_error&);
|
||||||
json(json::value_t::number_float).get<json::string_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_float).get<json::string_t>(),
|
||||||
"[json.exception.type_error.302] type must be string, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be string, but is number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(JSON_HAS_CPP_17)
|
#if defined(JSON_HAS_CPP_17)
|
||||||
SECTION("exception in case of a non-string type using string_view")
|
SECTION("exception in case of a non-string type using string_view")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::null).get<std::string_view>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::null).get<std::string_view>(),
|
||||||
"[json.exception.type_error.302] type must be string, but is null", json::type_error&);
|
"[json.exception.type_error.302] type must be string, but is null",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<std::string_view>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<std::string_view>(),
|
||||||
"[json.exception.type_error.302] type must be string, but is object", json::type_error&);
|
"[json.exception.type_error.302] type must be string, but is object",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::array).get<std::string_view>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::array).get<std::string_view>(),
|
||||||
"[json.exception.type_error.302] type must be string, but is array", json::type_error&);
|
"[json.exception.type_error.302] type must be string, but is array",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<std::string_view>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<std::string_view>(),
|
||||||
"[json.exception.type_error.302] type must be string, but is boolean", json::type_error&);
|
"[json.exception.type_error.302] type must be string, but is boolean",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::number_integer).get<std::string_view>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_integer).get<std::string_view>(),
|
||||||
"[json.exception.type_error.302] type must be string, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be string, but is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::number_unsigned).get<std::string_view>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_unsigned).get<std::string_view>(),
|
||||||
"[json.exception.type_error.302] type must be string, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be string, but is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::number_float).get<std::string_view>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_float).get<std::string_view>(),
|
||||||
"[json.exception.type_error.302] type must be string, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be string, but is number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -499,19 +486,26 @@ TEST_CASE("value conversion")
|
|||||||
CHECK(n2 == n);
|
CHECK(n2 == n);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::string).get<std::nullptr_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::string).get<std::nullptr_t>(),
|
||||||
"[json.exception.type_error.302] type must be null, but is string", json::type_error&);
|
"[json.exception.type_error.302] type must be null, but is string",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<std::nullptr_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<std::nullptr_t>(),
|
||||||
"[json.exception.type_error.302] type must be null, but is object", json::type_error&);
|
"[json.exception.type_error.302] type must be null, but is object",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::array).get<std::nullptr_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::array).get<std::nullptr_t>(),
|
||||||
"[json.exception.type_error.302] type must be null, but is array", json::type_error&);
|
"[json.exception.type_error.302] type must be null, but is array",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<std::nullptr_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<std::nullptr_t>(),
|
||||||
"[json.exception.type_error.302] type must be null, but is boolean", json::type_error&);
|
"[json.exception.type_error.302] type must be null, but is boolean",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::number_integer).get<std::nullptr_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_integer).get<std::nullptr_t>(),
|
||||||
"[json.exception.type_error.302] type must be null, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be null, but is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::number_unsigned).get<std::nullptr_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_unsigned).get<std::nullptr_t>(),
|
||||||
"[json.exception.type_error.302] type must be null, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be null, but is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::number_float).get<std::nullptr_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_float).get<std::nullptr_t>(),
|
||||||
"[json.exception.type_error.302] type must be null, but is number", json::type_error&);
|
"[json.exception.type_error.302] type must be null, but is number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if JSON_USE_IMPLICIT_CONVERSIONS
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
@@ -567,33 +561,34 @@ TEST_CASE("value conversion")
|
|||||||
|
|
||||||
SECTION("exception in case of a non-number type")
|
SECTION("exception in case of a non-number type")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_AS(json(json::value_t::string).get<uint8_t>(),
|
CHECK_THROWS_AS(json(json::value_t::string).get<uint8_t>(), json::type_error&);
|
||||||
json::type_error&);
|
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::null).get<json::boolean_t>(),
|
||||||
json(json::value_t::null).get<json::boolean_t>(),
|
"[json.exception.type_error.302] type must be boolean, but is null",
|
||||||
"[json.exception.type_error.302] type must be boolean, but is null", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<json::boolean_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<json::boolean_t>(),
|
||||||
"[json.exception.type_error.302] type must be boolean, "
|
"[json.exception.type_error.302] type must be boolean, "
|
||||||
"but is object", json::type_error&);
|
"but is object",
|
||||||
CHECK_THROWS_WITH_AS(
|
json::type_error&);
|
||||||
json(json::value_t::array).get<json::boolean_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::array).get<json::boolean_t>(),
|
||||||
"[json.exception.type_error.302] type must be boolean, but is array", json::type_error&);
|
"[json.exception.type_error.302] type must be boolean, but is array",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(json(json::value_t::string).get<json::boolean_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::string).get<json::boolean_t>(),
|
||||||
"[json.exception.type_error.302] type must be boolean, "
|
"[json.exception.type_error.302] type must be boolean, "
|
||||||
"but is string", json::type_error&);
|
"but is string",
|
||||||
CHECK_THROWS_WITH_AS(
|
json::type_error&);
|
||||||
json(json::value_t::number_integer).get<json::boolean_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_integer).get<json::boolean_t>(),
|
||||||
"[json.exception.type_error.302] type must be boolean, but is "
|
"[json.exception.type_error.302] type must be boolean, but is "
|
||||||
"number", json::type_error&);
|
"number",
|
||||||
CHECK_THROWS_WITH_AS(
|
json::type_error&);
|
||||||
json(json::value_t::number_unsigned).get<json::boolean_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_unsigned).get<json::boolean_t>(),
|
||||||
"[json.exception.type_error.302] type must be boolean, but is "
|
"[json.exception.type_error.302] type must be boolean, but is "
|
||||||
"number", json::type_error&);
|
"number",
|
||||||
CHECK_THROWS_WITH_AS(
|
json::type_error&);
|
||||||
json(json::value_t::number_float).get<json::boolean_t>(),
|
CHECK_THROWS_WITH_AS(json(json::value_t::number_float).get<json::boolean_t>(),
|
||||||
"[json.exception.type_error.302] type must be boolean, but is "
|
"[json.exception.type_error.302] type must be boolean, but is "
|
||||||
"number", json::type_error&);
|
"number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,27 +825,25 @@ TEST_CASE("value conversion")
|
|||||||
|
|
||||||
SECTION("exception in case of a non-number type")
|
SECTION("exception in case of a non-number type")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::null).get<json::number_integer_t>(),
|
||||||
json(json::value_t::null).get<json::number_integer_t>(),
|
"[json.exception.type_error.302] type must be number, but is null",
|
||||||
"[json.exception.type_error.302] type must be number, but is null", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<json::number_integer_t>(),
|
||||||
json(json::value_t::object).get<json::number_integer_t>(),
|
"[json.exception.type_error.302] type must be number, but is object",
|
||||||
"[json.exception.type_error.302] type must be number, but is object", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::array).get<json::number_integer_t>(),
|
||||||
json(json::value_t::array).get<json::number_integer_t>(),
|
"[json.exception.type_error.302] type must be number, but is array",
|
||||||
"[json.exception.type_error.302] type must be number, but is array", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::string).get<json::number_integer_t>(),
|
||||||
json(json::value_t::string).get<json::number_integer_t>(),
|
"[json.exception.type_error.302] type must be number, but is string",
|
||||||
"[json.exception.type_error.302] type must be number, but is string", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<json::number_integer_t>(),
|
||||||
json(json::value_t::boolean).get<json::number_integer_t>(),
|
|
||||||
"[json.exception.type_error.302] type must be number, but is "
|
"[json.exception.type_error.302] type must be number, but is "
|
||||||
"boolean", json::type_error&);
|
"boolean",
|
||||||
|
json::type_error&);
|
||||||
|
|
||||||
CHECK_NOTHROW(
|
CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_integer_t>());
|
||||||
json(json::value_t::number_float).get<json::number_integer_t>());
|
CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_unsigned_t>());
|
||||||
CHECK_NOTHROW(
|
|
||||||
json(json::value_t::number_float).get<json::number_unsigned_t>());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1093,27 +1086,25 @@ TEST_CASE("value conversion")
|
|||||||
|
|
||||||
SECTION("exception in case of a non-string type")
|
SECTION("exception in case of a non-string type")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::null).get<json::number_float_t>(),
|
||||||
json(json::value_t::null).get<json::number_float_t>(),
|
"[json.exception.type_error.302] type must be number, but is null",
|
||||||
"[json.exception.type_error.302] type must be number, but is null", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<json::number_float_t>(),
|
||||||
json(json::value_t::object).get<json::number_float_t>(),
|
"[json.exception.type_error.302] type must be number, but is object",
|
||||||
"[json.exception.type_error.302] type must be number, but is object", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::array).get<json::number_float_t>(),
|
||||||
json(json::value_t::array).get<json::number_float_t>(),
|
"[json.exception.type_error.302] type must be number, but is array",
|
||||||
"[json.exception.type_error.302] type must be number, but is array", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::string).get<json::number_float_t>(),
|
||||||
json(json::value_t::string).get<json::number_float_t>(),
|
"[json.exception.type_error.302] type must be number, but is string",
|
||||||
"[json.exception.type_error.302] type must be number, but is string", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<json::number_float_t>(),
|
||||||
json(json::value_t::boolean).get<json::number_float_t>(),
|
|
||||||
"[json.exception.type_error.302] type must be number, but is "
|
"[json.exception.type_error.302] type must be number, but is "
|
||||||
"boolean", json::type_error&);
|
"boolean",
|
||||||
|
json::type_error&);
|
||||||
|
|
||||||
CHECK_NOTHROW(
|
CHECK_NOTHROW(json(json::value_t::number_integer).get<json::number_float_t>());
|
||||||
json(json::value_t::number_integer).get<json::number_float_t>());
|
CHECK_NOTHROW(json(json::value_t::number_unsigned).get<json::number_float_t>());
|
||||||
CHECK_NOTHROW(
|
|
||||||
json(json::value_t::number_unsigned).get<json::number_float_t>());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1183,69 +1174,31 @@ TEST_CASE("value conversion")
|
|||||||
const json j_string_const(json::value_t::string);
|
const json j_string_const(json::value_t::string);
|
||||||
const json j_boolean_const(json::value_t::boolean);
|
const json j_boolean_const(json::value_t::boolean);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j_null.get<json::binary_t>(),
|
CHECK_THROWS_WITH_AS(j_null.get<json::binary_t>(), "[json.exception.type_error.302] type must be binary, but is null", json::type_error&);
|
||||||
"[json.exception.type_error.302] type must be binary, but is null",
|
CHECK_THROWS_WITH_AS(j_object.get<json::binary_t>(), "[json.exception.type_error.302] type must be binary, but is object", json::type_error&);
|
||||||
json::type_error&);
|
CHECK_THROWS_WITH_AS(j_array.get<json::binary_t>(), "[json.exception.type_error.302] type must be binary, but is array", json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_object.get<json::binary_t>(),
|
CHECK_THROWS_WITH_AS(j_string.get<json::binary_t>(), "[json.exception.type_error.302] type must be binary, but is string", json::type_error&);
|
||||||
"[json.exception.type_error.302] type must be binary, but is object",
|
CHECK_THROWS_WITH_AS(j_boolean.get<json::binary_t>(), "[json.exception.type_error.302] type must be binary, but is boolean", json::type_error&);
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_array.get<json::binary_t>(),
|
|
||||||
"[json.exception.type_error.302] type must be binary, but is array",
|
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_string.get<json::binary_t>(),
|
|
||||||
"[json.exception.type_error.302] type must be binary, but is string",
|
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_boolean.get<json::binary_t>(),
|
|
||||||
"[json.exception.type_error.302] type must be binary, but is boolean",
|
|
||||||
json::type_error&);
|
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j_null_const.get<json::binary_t>(),
|
CHECK_THROWS_WITH_AS(j_null_const.get<json::binary_t>(), "[json.exception.type_error.302] type must be binary, but is null", json::type_error&);
|
||||||
"[json.exception.type_error.302] type must be binary, but is null",
|
CHECK_THROWS_WITH_AS(j_object_const.get<json::binary_t>(), "[json.exception.type_error.302] type must be binary, but is object", json::type_error&);
|
||||||
json::type_error&);
|
CHECK_THROWS_WITH_AS(j_array_const.get<json::binary_t>(), "[json.exception.type_error.302] type must be binary, but is array", json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_object_const.get<json::binary_t>(),
|
CHECK_THROWS_WITH_AS(j_string_const.get<json::binary_t>(), "[json.exception.type_error.302] type must be binary, but is string", json::type_error&);
|
||||||
"[json.exception.type_error.302] type must be binary, but is object",
|
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_array_const.get<json::binary_t>(),
|
|
||||||
"[json.exception.type_error.302] type must be binary, but is array",
|
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_string_const.get<json::binary_t>(),
|
|
||||||
"[json.exception.type_error.302] type must be binary, but is string",
|
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_boolean_const.get<json::binary_t>(),
|
CHECK_THROWS_WITH_AS(j_boolean_const.get<json::binary_t>(),
|
||||||
"[json.exception.type_error.302] type must be binary, but is boolean",
|
"[json.exception.type_error.302] type must be binary, but is boolean",
|
||||||
json::type_error&);
|
json::type_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j_null.get_binary(),
|
CHECK_THROWS_WITH_AS(j_null.get_binary(), "[json.exception.type_error.302] type must be binary, but is null", json::type_error&);
|
||||||
"[json.exception.type_error.302] type must be binary, but is null",
|
CHECK_THROWS_WITH_AS(j_object.get_binary(), "[json.exception.type_error.302] type must be binary, but is object", json::type_error&);
|
||||||
json::type_error&);
|
CHECK_THROWS_WITH_AS(j_array.get_binary(), "[json.exception.type_error.302] type must be binary, but is array", json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_object.get_binary(),
|
CHECK_THROWS_WITH_AS(j_string.get_binary(), "[json.exception.type_error.302] type must be binary, but is string", json::type_error&);
|
||||||
"[json.exception.type_error.302] type must be binary, but is object",
|
CHECK_THROWS_WITH_AS(j_boolean.get_binary(), "[json.exception.type_error.302] type must be binary, but is boolean", json::type_error&);
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_array.get_binary(),
|
|
||||||
"[json.exception.type_error.302] type must be binary, but is array",
|
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_string.get_binary(),
|
|
||||||
"[json.exception.type_error.302] type must be binary, but is string",
|
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_boolean.get_binary(),
|
|
||||||
"[json.exception.type_error.302] type must be binary, but is boolean",
|
|
||||||
json::type_error&);
|
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j_null_const.get_binary(),
|
CHECK_THROWS_WITH_AS(j_null_const.get_binary(), "[json.exception.type_error.302] type must be binary, but is null", json::type_error&);
|
||||||
"[json.exception.type_error.302] type must be binary, but is null",
|
CHECK_THROWS_WITH_AS(j_object_const.get_binary(), "[json.exception.type_error.302] type must be binary, but is object", json::type_error&);
|
||||||
json::type_error&);
|
CHECK_THROWS_WITH_AS(j_array_const.get_binary(), "[json.exception.type_error.302] type must be binary, but is array", json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_object_const.get_binary(),
|
CHECK_THROWS_WITH_AS(j_string_const.get_binary(), "[json.exception.type_error.302] type must be binary, but is string", json::type_error&);
|
||||||
"[json.exception.type_error.302] type must be binary, but is object",
|
CHECK_THROWS_WITH_AS(j_boolean_const.get_binary(), "[json.exception.type_error.302] type must be binary, but is boolean", json::type_error&);
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_array_const.get_binary(),
|
|
||||||
"[json.exception.type_error.302] type must be binary, but is array",
|
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_string_const.get_binary(),
|
|
||||||
"[json.exception.type_error.302] type must be binary, but is string",
|
|
||||||
json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_boolean_const.get_binary(),
|
|
||||||
"[json.exception.type_error.302] type must be binary, but is boolean",
|
|
||||||
json::type_error&);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1265,8 +1218,16 @@ TEST_CASE("value conversion")
|
|||||||
|
|
||||||
SECTION("get an enum")
|
SECTION("get an enum")
|
||||||
{
|
{
|
||||||
enum c_enum { value_1, value_2 };
|
enum c_enum
|
||||||
enum class cpp_enum { value_1, value_2 };
|
{
|
||||||
|
value_1,
|
||||||
|
value_2
|
||||||
|
};
|
||||||
|
enum class cpp_enum
|
||||||
|
{
|
||||||
|
value_1,
|
||||||
|
value_2
|
||||||
|
};
|
||||||
|
|
||||||
CHECK(json(value_1).get<c_enum>() == value_1);
|
CHECK(json(value_1).get<c_enum>() == value_1);
|
||||||
CHECK(json(cpp_enum::value_1).get<cpp_enum>() == cpp_enum::value_1);
|
CHECK(json(cpp_enum::value_1).get<cpp_enum>() == cpp_enum::value_1);
|
||||||
@@ -1323,9 +1284,9 @@ TEST_CASE("value conversion")
|
|||||||
|
|
||||||
SECTION("exception in case of a non-object type")
|
SECTION("exception in case of a non-object type")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS((json().get<std::map<std::string, int>>()),
|
||||||
(json().get<std::map<std::string, int>>()),
|
"[json.exception.type_error.302] type must be object, but is null",
|
||||||
"[json.exception.type_error.302] type must be object, but is null", json::type_error&);
|
json::type_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1366,8 +1327,10 @@ TEST_CASE("value conversion")
|
|||||||
SECTION("std::array is larger than JSON")
|
SECTION("std::array is larger than JSON")
|
||||||
{
|
{
|
||||||
std::array<int, 6> arr6 = { { 1, 2, 3, 4, 5, 6 } };
|
std::array<int, 6> arr6 = { { 1, 2, 3, 4, 5, 6 } };
|
||||||
CHECK_THROWS_WITH_AS(j1.get_to(arr6), "[json.exception.out_of_range.401] "
|
CHECK_THROWS_WITH_AS(j1.get_to(arr6),
|
||||||
"array index 4 is out of range", json::out_of_range&);
|
"[json.exception.out_of_range.401] "
|
||||||
|
"array index 4 is out of range",
|
||||||
|
json::out_of_range&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("std::array is smaller than JSON")
|
SECTION("std::array is smaller than JSON")
|
||||||
@@ -1436,10 +1399,12 @@ TEST_CASE("value conversion")
|
|||||||
json const j8 = 2;
|
json const j8 = 2;
|
||||||
CHECK_THROWS_WITH_AS((j7.get<std::map<int, int>>()),
|
CHECK_THROWS_WITH_AS((j7.get<std::map<int, int>>()),
|
||||||
"[json.exception.type_error.302] type must be array, "
|
"[json.exception.type_error.302] type must be array, "
|
||||||
"but is number", json::type_error&);
|
"but is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS((j8.get<std::map<int, int>>()),
|
CHECK_THROWS_WITH_AS((j8.get<std::map<int, int>>()),
|
||||||
"[json.exception.type_error.302] type must be array, "
|
"[json.exception.type_error.302] type must be array, "
|
||||||
"but is number", json::type_error&);
|
"but is number",
|
||||||
|
json::type_error&);
|
||||||
|
|
||||||
SECTION("superfluous entries")
|
SECTION("superfluous entries")
|
||||||
{
|
{
|
||||||
@@ -1461,10 +1426,12 @@ TEST_CASE("value conversion")
|
|||||||
json const j8 = 2;
|
json const j8 = 2;
|
||||||
CHECK_THROWS_WITH_AS((j7.get<std::unordered_map<int, int>>()),
|
CHECK_THROWS_WITH_AS((j7.get<std::unordered_map<int, int>>()),
|
||||||
"[json.exception.type_error.302] type must be array, "
|
"[json.exception.type_error.302] type must be array, "
|
||||||
"but is number", json::type_error&);
|
"but is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS((j8.get<std::unordered_map<int, int>>()),
|
CHECK_THROWS_WITH_AS((j8.get<std::unordered_map<int, int>>()),
|
||||||
"[json.exception.type_error.302] type must be array, "
|
"[json.exception.type_error.302] type must be array, "
|
||||||
"but is number", json::type_error&);
|
"but is number",
|
||||||
|
json::type_error&);
|
||||||
|
|
||||||
SECTION("superfluous entries")
|
SECTION("superfluous entries")
|
||||||
{
|
{
|
||||||
@@ -1478,40 +1445,32 @@ TEST_CASE("value conversion")
|
|||||||
{
|
{
|
||||||
// does type really must be an array? or it rather must not be null?
|
// does type really must be an array? or it rather must not be null?
|
||||||
// that's what I thought when other test like this one broke
|
// that's what I thought when other test like this one broke
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS((json().get<std::list<int>>()), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
||||||
(json().get<std::list<int>>()),
|
CHECK_THROWS_WITH_AS((json().get<std::vector<int>>()), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
||||||
"[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
CHECK_THROWS_WITH_AS((json().get<std::vector<json>>()), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
CHECK_THROWS_WITH_AS((json().get<std::list<json>>()), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
||||||
(json().get<std::vector<int>>()),
|
CHECK_THROWS_WITH_AS((json().get<std::valarray<int>>()), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
||||||
"[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
CHECK_THROWS_WITH_AS((json().get<std::map<int, int>>()), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(
|
|
||||||
(json().get<std::vector<json>>()),
|
|
||||||
"[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(
|
|
||||||
(json().get<std::list<json>>()),
|
|
||||||
"[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(
|
|
||||||
(json().get<std::valarray<int>>()),
|
|
||||||
"[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
|
||||||
CHECK_THROWS_WITH_AS(
|
|
||||||
(json().get<std::map<int, int>>()),
|
|
||||||
"[json.exception.type_error.302] type must be array, but is null", json::type_error&);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class cards {kreuz, pik, herz, karo};
|
enum class cards
|
||||||
|
{
|
||||||
|
kreuz,
|
||||||
|
pik,
|
||||||
|
herz,
|
||||||
|
karo
|
||||||
|
};
|
||||||
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
||||||
NLOHMANN_JSON_SERIALIZE_ENUM(cards,
|
NLOHMANN_JSON_SERIALIZE_ENUM(cards,
|
||||||
{
|
{ { cards::kreuz, "kreuz" },
|
||||||
{cards::kreuz, "kreuz"},
|
|
||||||
{ cards::pik, "pik" },
|
{ cards::pik, "pik" },
|
||||||
{ cards::pik, "puk" }, // second entry for cards::puk; will not be used
|
{ cards::pik, "puk" }, // second entry for cards::puk; will not be used
|
||||||
{ cards::herz, "herz" },
|
{ cards::herz, "herz" },
|
||||||
{cards::karo, "karo"}
|
{ cards::karo, "karo" } })
|
||||||
})
|
|
||||||
|
|
||||||
enum TaskState
|
enum TaskState
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,14 +30,13 @@ class json_metadata
|
|||||||
{
|
{
|
||||||
return m_metadata;
|
return m_metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
metadata_t m_metadata = {};
|
metadata_t m_metadata = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
using json_with_metadata =
|
using json_with_metadata = nlohmann::basic_json<std::map,
|
||||||
nlohmann::basic_json <
|
|
||||||
std::map,
|
|
||||||
std::vector,
|
std::vector,
|
||||||
std::string,
|
std::string,
|
||||||
bool,
|
bool,
|
||||||
@@ -47,8 +46,7 @@ using json_with_metadata =
|
|||||||
std::allocator,
|
std::allocator,
|
||||||
nlohmann::adl_serializer,
|
nlohmann::adl_serializer,
|
||||||
std::vector<std::uint8_t>,
|
std::vector<std::uint8_t>,
|
||||||
json_metadata<T>
|
json_metadata<T>>;
|
||||||
>;
|
|
||||||
|
|
||||||
TEST_CASE("JSON Node Metadata")
|
TEST_CASE("JSON Node Metadata")
|
||||||
{
|
{
|
||||||
@@ -190,13 +188,13 @@ class visitor_adaptor
|
|||||||
public:
|
public:
|
||||||
template<class Fnc>
|
template<class Fnc>
|
||||||
void visit(const Fnc& fnc) const;
|
void visit(const Fnc& fnc) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<class Ptr, class Fnc>
|
template<class Ptr, class Fnc>
|
||||||
void do_visit(const Ptr& ptr, const Fnc& fnc) const;
|
void do_visit(const Ptr& ptr, const Fnc& fnc) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
using json_with_visitor_t = nlohmann::basic_json <
|
using json_with_visitor_t = nlohmann::basic_json<std::map,
|
||||||
std::map,
|
|
||||||
std::vector,
|
std::vector,
|
||||||
std::string,
|
std::string,
|
||||||
bool,
|
bool,
|
||||||
@@ -206,8 +204,7 @@ using json_with_visitor_t = nlohmann::basic_json <
|
|||||||
std::allocator,
|
std::allocator,
|
||||||
nlohmann::adl_serializer,
|
nlohmann::adl_serializer,
|
||||||
std::vector<std::uint8_t>,
|
std::vector<std::uint8_t>,
|
||||||
visitor_adaptor
|
visitor_adaptor>;
|
||||||
>;
|
|
||||||
|
|
||||||
template<class Fnc>
|
template<class Fnc>
|
||||||
void visitor_adaptor::visit(const Fnc& fnc) const
|
void visitor_adaptor::visit(const Fnc& fnc) const
|
||||||
@@ -261,9 +258,7 @@ TEST_CASE("JSON Visit Node")
|
|||||||
json["array"].push_back(1);
|
json["array"].push_back(1);
|
||||||
json["array"].push_back(json);
|
json["array"].push_back(json);
|
||||||
|
|
||||||
std::set<std::string> expected
|
std::set<std::string> expected{ "/null - null - null",
|
||||||
{
|
|
||||||
"/null - null - null",
|
|
||||||
"/int - number_integer - -1",
|
"/int - number_integer - -1",
|
||||||
"/uint - number_unsigned - 1",
|
"/uint - number_unsigned - 1",
|
||||||
"/float - number_float - 1.0",
|
"/float - number_float - 1.0",
|
||||||
@@ -279,13 +274,9 @@ TEST_CASE("JSON Visit Node")
|
|||||||
"/array/2/boolean - boolean - true",
|
"/array/2/boolean - boolean - true",
|
||||||
"/array/2/string - string - \"string\"",
|
"/array/2/string - string - \"string\"",
|
||||||
"/array/2/array/0 - number_integer - 0",
|
"/array/2/array/0 - number_integer - 0",
|
||||||
"/array/2/array/1 - number_integer - 1"
|
"/array/2/array/1 - number_integer - 1" };
|
||||||
};
|
|
||||||
|
|
||||||
json.visit(
|
json.visit([&](const json_with_visitor_t::json_pointer& p, const json_with_visitor_t& j) {
|
||||||
[&](const json_with_visitor_t::json_pointer & p,
|
|
||||||
const json_with_visitor_t& j)
|
|
||||||
{
|
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
str << p.to_string() << " - ";
|
str << p.to_string() << " - ";
|
||||||
using value_t = nlohmann::detail::value_t;
|
using value_t = nlohmann::detail::value_t;
|
||||||
@@ -330,7 +321,6 @@ TEST_CASE("JSON Visit Node")
|
|||||||
INFO(str.str());
|
INFO(str.str());
|
||||||
CHECK(expected.count(str.str()) == 1);
|
CHECK(expected.count(str.str()) == 1);
|
||||||
expected.erase(str.str());
|
expected.erase(str.str());
|
||||||
}
|
});
|
||||||
);
|
|
||||||
CHECK(expected.empty());
|
CHECK(expected.empty());
|
||||||
}
|
}
|
||||||
|
|||||||
+171
-138
@@ -177,12 +177,13 @@ class proxy_iterator
|
|||||||
using value_type = typename std::iterator_traits<iterator>::value_type;
|
using value_type = typename std::iterator_traits<iterator>::value_type;
|
||||||
using reference = typename std::iterator_traits<iterator>::reference;
|
using reference = typename std::iterator_traits<iterator>::reference;
|
||||||
using pointer = typename std::iterator_traits<iterator>::pointer;
|
using pointer = typename std::iterator_traits<iterator>::pointer;
|
||||||
using difference_type =
|
using difference_type = typename std::iterator_traits<iterator>::difference_type;
|
||||||
typename std::iterator_traits<iterator>::difference_type;
|
|
||||||
using iterator_category = std::input_iterator_tag;
|
using iterator_category = std::input_iterator_tag;
|
||||||
|
|
||||||
proxy_iterator() = default;
|
proxy_iterator() = default;
|
||||||
explicit proxy_iterator(iterator& it) : m_it(std::addressof(it)) {}
|
explicit proxy_iterator(iterator& it)
|
||||||
|
: m_it(std::addressof(it))
|
||||||
|
{}
|
||||||
|
|
||||||
proxy_iterator& operator++()
|
proxy_iterator& operator++()
|
||||||
{
|
{
|
||||||
@@ -235,13 +236,17 @@ TEST_CASE("deserialization")
|
|||||||
SaxEventLogger l;
|
SaxEventLogger l;
|
||||||
CHECK(json::sax_parse(ss3, &l));
|
CHECK(json::sax_parse(ss3, &l));
|
||||||
CHECK(l.events.size() == 11);
|
CHECK(l.events.size() == 11);
|
||||||
CHECK(l.events == std::vector<std::string>(
|
CHECK(l.events == std::vector<std::string>({ "start_array()",
|
||||||
{
|
"string(foo)",
|
||||||
"start_array()", "string(foo)", "number_unsigned(1)",
|
"number_unsigned(1)",
|
||||||
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
|
"number_unsigned(2)",
|
||||||
"start_object()", "key(one)", "number_unsigned(1)",
|
"number_unsigned(3)",
|
||||||
"end_object()", "end_array()"
|
"boolean(false)",
|
||||||
}));
|
"start_object()",
|
||||||
|
"key(one)",
|
||||||
|
"number_unsigned(1)",
|
||||||
|
"end_object()",
|
||||||
|
"end_array()" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("string literal")
|
SECTION("string literal")
|
||||||
@@ -254,13 +259,17 @@ TEST_CASE("deserialization")
|
|||||||
SaxEventLogger l;
|
SaxEventLogger l;
|
||||||
CHECK(json::sax_parse(s, &l));
|
CHECK(json::sax_parse(s, &l));
|
||||||
CHECK(l.events.size() == 11);
|
CHECK(l.events.size() == 11);
|
||||||
CHECK(l.events == std::vector<std::string>(
|
CHECK(l.events == std::vector<std::string>({ "start_array()",
|
||||||
{
|
"string(foo)",
|
||||||
"start_array()", "string(foo)", "number_unsigned(1)",
|
"number_unsigned(1)",
|
||||||
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
|
"number_unsigned(2)",
|
||||||
"start_object()", "key(one)", "number_unsigned(1)",
|
"number_unsigned(3)",
|
||||||
"end_object()", "end_array()"
|
"boolean(false)",
|
||||||
}));
|
"start_object()",
|
||||||
|
"key(one)",
|
||||||
|
"number_unsigned(1)",
|
||||||
|
"end_object()",
|
||||||
|
"end_array()" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("string_t")
|
SECTION("string_t")
|
||||||
@@ -273,13 +282,17 @@ TEST_CASE("deserialization")
|
|||||||
SaxEventLogger l;
|
SaxEventLogger l;
|
||||||
CHECK(json::sax_parse(s, &l));
|
CHECK(json::sax_parse(s, &l));
|
||||||
CHECK(l.events.size() == 11);
|
CHECK(l.events.size() == 11);
|
||||||
CHECK(l.events == std::vector<std::string>(
|
CHECK(l.events == std::vector<std::string>({ "start_array()",
|
||||||
{
|
"string(foo)",
|
||||||
"start_array()", "string(foo)", "number_unsigned(1)",
|
"number_unsigned(1)",
|
||||||
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
|
"number_unsigned(2)",
|
||||||
"start_object()", "key(one)", "number_unsigned(1)",
|
"number_unsigned(3)",
|
||||||
"end_object()", "end_array()"
|
"boolean(false)",
|
||||||
}));
|
"start_object()",
|
||||||
|
"key(one)",
|
||||||
|
"number_unsigned(1)",
|
||||||
|
"end_object()",
|
||||||
|
"end_array()" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("operator<<")
|
SECTION("operator<<")
|
||||||
@@ -320,7 +333,10 @@ TEST_CASE("deserialization")
|
|||||||
ss5 << R"(["foo",1,2,3,false,{"one":1})";
|
ss5 << R"(["foo",1,2,3,false,{"one":1})";
|
||||||
|
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(ss1), "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(ss1),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'",
|
||||||
|
json::parse_error&);
|
||||||
CHECK(!json::accept(ss3));
|
CHECK(!json::accept(ss3));
|
||||||
|
|
||||||
json j_error;
|
json j_error;
|
||||||
@@ -330,20 +346,27 @@ TEST_CASE("deserialization")
|
|||||||
SaxEventLogger l;
|
SaxEventLogger l;
|
||||||
CHECK(!json::sax_parse(ss5, &l));
|
CHECK(!json::sax_parse(ss5, &l));
|
||||||
CHECK(l.events.size() == 11);
|
CHECK(l.events.size() == 11);
|
||||||
CHECK(l.events == std::vector<std::string>(
|
CHECK(l.events == std::vector<std::string>({ "start_array()",
|
||||||
{
|
"string(foo)",
|
||||||
"start_array()", "string(foo)", "number_unsigned(1)",
|
"number_unsigned(1)",
|
||||||
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
|
"number_unsigned(2)",
|
||||||
"start_object()", "key(one)", "number_unsigned(1)",
|
"number_unsigned(3)",
|
||||||
"end_object()", "parse_error(29)"
|
"boolean(false)",
|
||||||
}));
|
"start_object()",
|
||||||
|
"key(one)",
|
||||||
|
"number_unsigned(1)",
|
||||||
|
"end_object()",
|
||||||
|
"parse_error(29)" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("string")
|
SECTION("string")
|
||||||
{
|
{
|
||||||
json::string_t const s = R"(["foo",1,2,3,false,{"one":1})";
|
json::string_t const s = R"(["foo",1,2,3,false,{"one":1})";
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(s), "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(s),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'",
|
||||||
|
json::parse_error&);
|
||||||
CHECK(!json::accept(s));
|
CHECK(!json::accept(s));
|
||||||
|
|
||||||
json j_error;
|
json j_error;
|
||||||
@@ -353,13 +376,17 @@ TEST_CASE("deserialization")
|
|||||||
SaxEventLogger l;
|
SaxEventLogger l;
|
||||||
CHECK(!json::sax_parse(s, &l));
|
CHECK(!json::sax_parse(s, &l));
|
||||||
CHECK(l.events.size() == 11);
|
CHECK(l.events.size() == 11);
|
||||||
CHECK(l.events == std::vector<std::string>(
|
CHECK(l.events == std::vector<std::string>({ "start_array()",
|
||||||
{
|
"string(foo)",
|
||||||
"start_array()", "string(foo)", "number_unsigned(1)",
|
"number_unsigned(1)",
|
||||||
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
|
"number_unsigned(2)",
|
||||||
"start_object()", "key(one)", "number_unsigned(1)",
|
"number_unsigned(3)",
|
||||||
"end_object()", "parse_error(29)"
|
"boolean(false)",
|
||||||
}));
|
"start_object()",
|
||||||
|
"key(one)",
|
||||||
|
"number_unsigned(1)",
|
||||||
|
"end_object()",
|
||||||
|
"parse_error(29)" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("operator<<")
|
SECTION("operator<<")
|
||||||
@@ -367,7 +394,10 @@ TEST_CASE("deserialization")
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << R"(["foo",1,2,3,false,{"one":1})";
|
ss << R"(["foo",1,2,3,false,{"one":1})";
|
||||||
json j;
|
json j;
|
||||||
CHECK_THROWS_WITH_AS(j << ss, "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
j << ss,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("operator>>")
|
SECTION("operator>>")
|
||||||
@@ -375,12 +405,18 @@ TEST_CASE("deserialization")
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << R"(["foo",1,2,3,false,{"one":1})";
|
ss << R"(["foo",1,2,3,false,{"one":1})";
|
||||||
json j;
|
json j;
|
||||||
CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
ss >> j,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("user-defined string literal")
|
SECTION("user-defined string literal")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
"[\"foo\",1,2,3,false,{\"one\":1}"_json,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +529,6 @@ TEST_CASE("deserialization")
|
|||||||
CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
|
CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
|
||||||
CHECK(l.events.size() == 1);
|
CHECK(l.events.size() == 1);
|
||||||
CHECK(l.events == std::vector<std::string>({ "boolean(true)" }));
|
CHECK(l.events == std::vector<std::string>({ "boolean(true)" }));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("from std::array")
|
SECTION("from std::array")
|
||||||
@@ -585,8 +620,7 @@ TEST_CASE("deserialization")
|
|||||||
json j;
|
json j;
|
||||||
json_sax_dom_parser<json> sax(j, true);
|
json_sax_dom_parser<json> sax(j, true);
|
||||||
|
|
||||||
CHECK(json::sax_parse(proxy(first), proxy(last), &sax,
|
CHECK(json::sax_parse(proxy(first), proxy(last), &sax, input_format_t::json, false));
|
||||||
input_format_t::json, false));
|
|
||||||
CHECK(j.dump() == str1);
|
CHECK(j.dump() == str1);
|
||||||
CHECK(std::string(first, last) == str2);
|
CHECK(std::string(first, last) == str2);
|
||||||
}
|
}
|
||||||
@@ -684,7 +718,10 @@ TEST_CASE("deserialization")
|
|||||||
{
|
{
|
||||||
std::array<std::uint8_t, 4> v = { { '\"', 0x7F, 0xDF, 0x7F } };
|
std::array<std::uint8_t, 4> v = { { '\"', 0x7F, 0xDF, 0x7F } };
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(std::begin(v), std::end(v)), "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"\x7f\xdf\x7f'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(std::begin(v), std::end(v)),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"\x7f\xdf\x7f'",
|
||||||
|
json::parse_error&);
|
||||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
json j_error;
|
json j_error;
|
||||||
@@ -864,11 +901,7 @@ TEST_CASE("deserialization")
|
|||||||
SaxEventLogger l;
|
SaxEventLogger l;
|
||||||
CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
|
CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
|
||||||
CHECK(l.events.size() == 4);
|
CHECK(l.events.size() == 4);
|
||||||
CHECK(l.events == std::vector<std::string>(
|
CHECK(l.events == std::vector<std::string>({ "start_object()", "key()", "number_unsigned(11)", "parse_error(7)" }));
|
||||||
{
|
|
||||||
"start_object()", "key()", "number_unsigned(11)",
|
|
||||||
"parse_error(7)"
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -880,17 +913,20 @@ TEST_CASE("deserialization")
|
|||||||
SECTION("BOM only")
|
SECTION("BOM only")
|
||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(bom), "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(bom),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(std::istringstream(bom)), "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(std::istringstream(bom)),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
SaxEventLogger l;
|
SaxEventLogger l;
|
||||||
CHECK(!json::sax_parse(bom, &l));
|
CHECK(!json::sax_parse(bom, &l));
|
||||||
CHECK(l.events.size() == 1);
|
CHECK(l.events.size() == 1);
|
||||||
CHECK(l.events == std::vector<std::string>(
|
CHECK(l.events == std::vector<std::string>({ "parse_error(4)" }));
|
||||||
{
|
|
||||||
"parse_error(4)"
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("BOM and content")
|
SECTION("BOM and content")
|
||||||
@@ -903,61 +939,55 @@ TEST_CASE("deserialization")
|
|||||||
CHECK(json::sax_parse(std::istringstream(bom + "1"), &l1));
|
CHECK(json::sax_parse(std::istringstream(bom + "1"), &l1));
|
||||||
CHECK(json::sax_parse(bom + "1", &l2));
|
CHECK(json::sax_parse(bom + "1", &l2));
|
||||||
CHECK(l1.events.size() == 1);
|
CHECK(l1.events.size() == 1);
|
||||||
CHECK(l1.events == std::vector<std::string>(
|
CHECK(l1.events == std::vector<std::string>({ "number_unsigned(1)" }));
|
||||||
{
|
|
||||||
"number_unsigned(1)"
|
|
||||||
}));
|
|
||||||
CHECK(l2.events.size() == 1);
|
CHECK(l2.events.size() == 1);
|
||||||
CHECK(l2.events == std::vector<std::string>(
|
CHECK(l2.events == std::vector<std::string>({ "number_unsigned(1)" }));
|
||||||
{
|
|
||||||
"number_unsigned(1)"
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("2 byte of BOM")
|
SECTION("2 byte of BOM")
|
||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(bom.substr(0, 2)), "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(bom.substr(0, 2)),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(std::istringstream(bom.substr(0, 2))), "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(std::istringstream(bom.substr(0, 2))),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
SaxEventLogger l1;
|
SaxEventLogger l1;
|
||||||
SaxEventLogger l2;
|
SaxEventLogger l2;
|
||||||
CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 2)), &l1));
|
CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 2)), &l1));
|
||||||
CHECK(!json::sax_parse(bom.substr(0, 2), &l2));
|
CHECK(!json::sax_parse(bom.substr(0, 2), &l2));
|
||||||
CHECK(l1.events.size() == 1);
|
CHECK(l1.events.size() == 1);
|
||||||
CHECK(l1.events == std::vector<std::string>(
|
CHECK(l1.events == std::vector<std::string>({ "parse_error(3)" }));
|
||||||
{
|
|
||||||
"parse_error(3)"
|
|
||||||
}));
|
|
||||||
CHECK(l2.events.size() == 1);
|
CHECK(l2.events.size() == 1);
|
||||||
CHECK(l2.events == std::vector<std::string>(
|
CHECK(l2.events == std::vector<std::string>({ "parse_error(3)" }));
|
||||||
{
|
|
||||||
"parse_error(3)"
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("1 byte of BOM")
|
SECTION("1 byte of BOM")
|
||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(bom.substr(0, 1)), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(bom.substr(0, 1)),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(std::istringstream(bom.substr(0, 1))), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(std::istringstream(bom.substr(0, 1))),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
SaxEventLogger l1;
|
SaxEventLogger l1;
|
||||||
SaxEventLogger l2;
|
SaxEventLogger l2;
|
||||||
CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 1)), &l1));
|
CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 1)), &l1));
|
||||||
CHECK(!json::sax_parse(bom.substr(0, 1), &l2));
|
CHECK(!json::sax_parse(bom.substr(0, 1), &l2));
|
||||||
CHECK(l1.events.size() == 1);
|
CHECK(l1.events.size() == 1);
|
||||||
CHECK(l1.events == std::vector<std::string>(
|
CHECK(l1.events == std::vector<std::string>({ "parse_error(2)" }));
|
||||||
{
|
|
||||||
"parse_error(2)"
|
|
||||||
}));
|
|
||||||
CHECK(l2.events.size() == 1);
|
CHECK(l2.events.size() == 1);
|
||||||
CHECK(l2.events == std::vector<std::string>(
|
CHECK(l2.events == std::vector<std::string>({ "parse_error(2)" }));
|
||||||
{
|
|
||||||
"parse_error(2)"
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("variations")
|
SECTION("variations")
|
||||||
@@ -989,10 +1019,7 @@ TEST_CASE("deserialization")
|
|||||||
SaxEventLogger l;
|
SaxEventLogger l;
|
||||||
CHECK(json::sax_parse(s + "null", &l));
|
CHECK(json::sax_parse(s + "null", &l));
|
||||||
CHECK(l.events.size() == 1);
|
CHECK(l.events.size() == 1);
|
||||||
CHECK(l.events == std::vector<std::string>(
|
CHECK(l.events == std::vector<std::string>({ "null()" }));
|
||||||
{
|
|
||||||
"null()"
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1007,24 +1034,15 @@ TEST_CASE("deserialization")
|
|||||||
|
|
||||||
if (i0 != 0)
|
if (i0 != 0)
|
||||||
{
|
{
|
||||||
CHECK(l.events == std::vector<std::string>(
|
CHECK(l.events == std::vector<std::string>({ "parse_error(1)" }));
|
||||||
{
|
|
||||||
"parse_error(1)"
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
else if (i1 != 0)
|
else if (i1 != 0)
|
||||||
{
|
{
|
||||||
CHECK(l.events == std::vector<std::string>(
|
CHECK(l.events == std::vector<std::string>({ "parse_error(2)" }));
|
||||||
{
|
|
||||||
"parse_error(2)"
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CHECK(l.events == std::vector<std::string>(
|
CHECK(l.events == std::vector<std::string>({ "parse_error(3)" }));
|
||||||
{
|
|
||||||
"parse_error(3)"
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1054,38 +1072,47 @@ TEST_CASE("deserialization")
|
|||||||
|
|
||||||
json::sax_parse(s, &default_logger);
|
json::sax_parse(s, &default_logger);
|
||||||
CHECK(default_logger.events.size() == 14);
|
CHECK(default_logger.events.size() == 14);
|
||||||
CHECK(default_logger.events == std::vector<std::string>(
|
CHECK(default_logger.events == std::vector<std::string>({ "start_array()",
|
||||||
{
|
"number_unsigned(1)",
|
||||||
"start_array()", "number_unsigned(1)", "start_array()",
|
"start_array()",
|
||||||
"string(string)", "number_float(43.12)", "end_array()", "null()",
|
"string(string)",
|
||||||
"start_object()", "key(key1)", "boolean(true)", "key(key2)",
|
"number_float(43.12)",
|
||||||
"boolean(false)", "end_object()", "end_array()"
|
"end_array()",
|
||||||
}));
|
"null()",
|
||||||
|
"start_object()",
|
||||||
|
"key(key1)",
|
||||||
|
"boolean(true)",
|
||||||
|
"key(key2)",
|
||||||
|
"boolean(false)",
|
||||||
|
"end_object()",
|
||||||
|
"end_array()" }));
|
||||||
|
|
||||||
json::sax_parse(s, &exit_after_start_object);
|
json::sax_parse(s, &exit_after_start_object);
|
||||||
CHECK(exit_after_start_object.events.size() == 8);
|
CHECK(exit_after_start_object.events.size() == 8);
|
||||||
CHECK(exit_after_start_object.events == std::vector<std::string>(
|
CHECK(exit_after_start_object.events == std::vector<std::string>({ "start_array()",
|
||||||
{
|
"number_unsigned(1)",
|
||||||
"start_array()", "number_unsigned(1)", "start_array()",
|
"start_array()",
|
||||||
"string(string)", "number_float(43.12)", "end_array()", "null()",
|
"string(string)",
|
||||||
"start_object()"
|
"number_float(43.12)",
|
||||||
}));
|
"end_array()",
|
||||||
|
"null()",
|
||||||
|
"start_object()" }));
|
||||||
|
|
||||||
json::sax_parse(s, &exit_after_key);
|
json::sax_parse(s, &exit_after_key);
|
||||||
CHECK(exit_after_key.events.size() == 9);
|
CHECK(exit_after_key.events.size() == 9);
|
||||||
CHECK(exit_after_key.events == std::vector<std::string>(
|
CHECK(exit_after_key.events == std::vector<std::string>({ "start_array()",
|
||||||
{
|
"number_unsigned(1)",
|
||||||
"start_array()", "number_unsigned(1)", "start_array()",
|
"start_array()",
|
||||||
"string(string)", "number_float(43.12)", "end_array()", "null()",
|
"string(string)",
|
||||||
"start_object()", "key(key1)"
|
"number_float(43.12)",
|
||||||
}));
|
"end_array()",
|
||||||
|
"null()",
|
||||||
|
"start_object()",
|
||||||
|
"key(key1)" }));
|
||||||
|
|
||||||
json::sax_parse(s, &exit_after_start_array);
|
json::sax_parse(s, &exit_after_start_array);
|
||||||
CHECK(exit_after_start_array.events.size() == 1);
|
CHECK(exit_after_start_array.events.size() == 1);
|
||||||
CHECK(exit_after_start_array.events == std::vector<std::string>(
|
CHECK(exit_after_start_array.events == std::vector<std::string>({ "start_array()" }));
|
||||||
{
|
|
||||||
"start_array()"
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("JSON Lines")
|
SECTION("JSON Lines")
|
||||||
@@ -1131,13 +1158,20 @@ TEST_CASE("deserialization")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)", T,
|
TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)",
|
||||||
char, unsigned char, signed char,
|
T,
|
||||||
|
char,
|
||||||
|
unsigned char,
|
||||||
|
signed char,
|
||||||
wchar_t,
|
wchar_t,
|
||||||
char16_t, char32_t,
|
char16_t,
|
||||||
std::uint8_t, std::int8_t,
|
char32_t,
|
||||||
std::int16_t, std::uint16_t,
|
std::uint8_t,
|
||||||
std::int32_t, std::uint32_t)
|
std::int8_t,
|
||||||
|
std::int16_t,
|
||||||
|
std::uint16_t,
|
||||||
|
std::int32_t,
|
||||||
|
std::uint32_t)
|
||||||
{
|
{
|
||||||
std::vector<T> const v = { 't', 'r', 'u', 'e' };
|
std::vector<T> const v = { 't', 'r', 'u', 'e' };
|
||||||
CHECK(json::parse(v) == json(true));
|
CHECK(json::parse(v) == json(true));
|
||||||
@@ -1149,11 +1183,12 @@ TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)", T,
|
|||||||
CHECK(l.events == std::vector<std::string>({ "boolean(true)" }));
|
CHECK(l.events == std::vector<std::string>({ "boolean(true)" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-8)", T,
|
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-8)", T, char, unsigned char, std::uint8_t)
|
||||||
char, unsigned char, std::uint8_t)
|
|
||||||
{
|
{
|
||||||
// a star emoji
|
// a star emoji
|
||||||
std::vector<T> const v = {'"', static_cast<T>(0xe2u), static_cast<T>(0xadu), static_cast<T>(0x90u), static_cast<T>(0xefu), static_cast<T>(0xb8u), static_cast<T>(0x8fu), '"'};
|
std::vector<T> const v = {
|
||||||
|
'"', static_cast<T>(0xe2u), static_cast<T>(0xadu), static_cast<T>(0x90u), static_cast<T>(0xefu), static_cast<T>(0xb8u), static_cast<T>(0x8fu), '"'
|
||||||
|
};
|
||||||
CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
|
CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
|
||||||
CHECK(json::accept(v));
|
CHECK(json::accept(v));
|
||||||
|
|
||||||
@@ -1162,8 +1197,7 @@ TEST_CASE_TEMPLATE("deserialization of different character types (UTF-8)", T,
|
|||||||
CHECK(l.events.size() == 1);
|
CHECK(l.events.size() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-16)", T,
|
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-16)", T, char16_t, std::uint16_t)
|
||||||
char16_t, std::uint16_t)
|
|
||||||
{
|
{
|
||||||
// a star emoji
|
// a star emoji
|
||||||
std::vector<T> const v = { static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"') };
|
std::vector<T> const v = { static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"') };
|
||||||
@@ -1175,8 +1209,7 @@ TEST_CASE_TEMPLATE("deserialization of different character types (UTF-16)", T,
|
|||||||
CHECK(l.events.size() == 1);
|
CHECK(l.events.size() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-32)", T,
|
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-32)", T, char32_t, std::uint32_t)
|
||||||
char32_t, std::uint32_t)
|
|
||||||
{
|
{
|
||||||
// a star emoji
|
// a star emoji
|
||||||
std::vector<T> const v = { static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"') };
|
std::vector<T> const v = { static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"') };
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ TEST_CASE("Better diagnostics")
|
|||||||
json j;
|
json j;
|
||||||
j["a"]["b"]["c"] = 1;
|
j["a"]["b"]["c"] = 1;
|
||||||
std::string s;
|
std::string s;
|
||||||
CHECK_THROWS_WITH_AS(s = j["a"]["b"]["c"].get<std::string>(), "[json.exception.type_error.302] (/a/b/c) type must be string, but is number", json::type_error);
|
CHECK_THROWS_WITH_AS(s = j["a"]["b"]["c"].get<std::string>(),
|
||||||
|
"[json.exception.type_error.302] (/a/b/c) type must be string, but is number",
|
||||||
|
json::type_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("missing key")
|
SECTION("missing key")
|
||||||
@@ -53,14 +55,18 @@ TEST_CASE("Better diagnostics")
|
|||||||
{
|
{
|
||||||
json j;
|
json j;
|
||||||
j["array"][4] = true;
|
j["array"][4] = true;
|
||||||
CHECK_THROWS_WITH_AS(j["array"][4][5], "[json.exception.type_error.305] (/array/4) cannot use operator[] with a numeric argument with boolean", json::type_error);
|
CHECK_THROWS_WITH_AS(j["array"][4][5],
|
||||||
|
"[json.exception.type_error.305] (/array/4) cannot use operator[] with a numeric argument with boolean",
|
||||||
|
json::type_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("wrong iterator")
|
SECTION("wrong iterator")
|
||||||
{
|
{
|
||||||
json j;
|
json j;
|
||||||
j["array"] = json::array();
|
j["array"] = json::array();
|
||||||
CHECK_THROWS_WITH_AS(j["array"].erase(j.begin()), "[json.exception.invalid_iterator.202] (/array) iterator does not fit current value", json::invalid_iterator);
|
CHECK_THROWS_WITH_AS(j["array"].erase(j.begin()),
|
||||||
|
"[json.exception.invalid_iterator.202] (/array) iterator does not fit current value",
|
||||||
|
json::invalid_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("JSON Pointer escaping")
|
SECTION("JSON Pointer escaping")
|
||||||
@@ -68,13 +74,18 @@ TEST_CASE("Better diagnostics")
|
|||||||
json j;
|
json j;
|
||||||
j["a/b"]["m~n"] = 1;
|
j["a/b"]["m~n"] = 1;
|
||||||
std::string s;
|
std::string s;
|
||||||
CHECK_THROWS_WITH_AS(s = j["a/b"]["m~n"].get<std::string>(), "[json.exception.type_error.302] (/a~1b/m~0n) type must be string, but is number", json::type_error);
|
CHECK_THROWS_WITH_AS(s = j["a/b"]["m~n"].get<std::string>(),
|
||||||
|
"[json.exception.type_error.302] (/a~1b/m~0n) type must be string, but is number",
|
||||||
|
json::type_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Parse error")
|
SECTION("Parse error")
|
||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(""), "[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON",
|
||||||
|
json::parse_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Wrong type in update()")
|
SECTION("Wrong type in update()")
|
||||||
@@ -82,7 +93,9 @@ TEST_CASE("Better diagnostics")
|
|||||||
json j = { { "foo", "bar" } };
|
json j = { { "foo", "bar" } };
|
||||||
json k = { { "bla", 1 } };
|
json k = { { "bla", 1 } };
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j.update(k["bla"].begin(), k["bla"].end()), "[json.exception.type_error.312] (/bla) cannot use update() with number", json::type_error);
|
CHECK_THROWS_WITH_AS(j.update(k["bla"].begin(), k["bla"].end()),
|
||||||
|
"[json.exception.type_error.312] (/bla) cannot use update() with number",
|
||||||
|
json::type_error);
|
||||||
CHECK_THROWS_WITH_AS(j.update(k["bla"]), "[json.exception.type_error.312] (/bla) cannot use update() with number", json::type_error);
|
CHECK_THROWS_WITH_AS(j.update(k["bla"]), "[json.exception.type_error.312] (/bla) cannot use update() with number", json::type_error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ using json = nlohmann::json;
|
|||||||
class sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>
|
class sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit sax_no_exception(json& j) : nlohmann::detail::json_sax_dom_parser<json>(j, false) {}
|
explicit sax_no_exception(json& j)
|
||||||
|
: nlohmann::detail::json_sax_dom_parser<json>(j, false)
|
||||||
|
{}
|
||||||
|
|
||||||
static bool parse_error(std::size_t /*position*/, const std::string& /*last_token*/, const json::exception& ex)
|
static bool parse_error(std::size_t /*position*/, const std::string& /*last_token*/, const json::exception& ex)
|
||||||
{
|
{
|
||||||
@@ -44,7 +46,8 @@ TEST_CASE("Tests with disabled exceptions")
|
|||||||
sax_no_exception sax(j);
|
sax_no_exception sax(j);
|
||||||
|
|
||||||
CHECK(!json::sax_parse("xyz", &sax));
|
CHECK(!json::sax_parse("xyz", &sax));
|
||||||
CHECK(*sax_no_exception::error_string == "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'");
|
CHECK(*sax_no_exception::error_string ==
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'");
|
||||||
delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)
|
delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,10 +44,8 @@ TEST_CASE("element access 1")
|
|||||||
|
|
||||||
SECTION("access outside bounds")
|
SECTION("access outside bounds")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_AS(j.at(8),
|
CHECK_THROWS_WITH_AS(j.at(8), "[json.exception.out_of_range.401] array index 8 is out of range", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.401] array index 8 is out of range", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(j_const.at(8), "[json.exception.out_of_range.401] array index 8 is out of range", json::out_of_range&);
|
||||||
CHECK_THROWS_WITH_AS(j_const.at(8),
|
|
||||||
"[json.exception.out_of_range.401] array index 8 is out of range", json::out_of_range&);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("access on non-array type")
|
SECTION("access on non-array type")
|
||||||
@@ -157,7 +155,9 @@ TEST_CASE("element access 1")
|
|||||||
json j_nonarray(json::value_t::null);
|
json j_nonarray(json::value_t::null);
|
||||||
const json j_nonarray_const(j_nonarray);
|
const json j_nonarray_const(j_nonarray);
|
||||||
CHECK_NOTHROW(j_nonarray[0]);
|
CHECK_NOTHROW(j_nonarray[0]);
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with null", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonarray_const[0],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with null",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("implicit transformation to properly filled array")
|
SECTION("implicit transformation to properly filled array")
|
||||||
@@ -172,48 +172,72 @@ TEST_CASE("element access 1")
|
|||||||
{
|
{
|
||||||
json j_nonarray(json::value_t::boolean);
|
json j_nonarray(json::value_t::boolean);
|
||||||
const json j_nonarray_const(j_nonarray);
|
const json j_nonarray_const(j_nonarray);
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with boolean", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonarray[0],
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with boolean", json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with boolean",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonarray_const[0],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with boolean",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("string")
|
SECTION("string")
|
||||||
{
|
{
|
||||||
json j_nonarray(json::value_t::string);
|
json j_nonarray(json::value_t::string);
|
||||||
const json j_nonarray_const(j_nonarray);
|
const json j_nonarray_const(j_nonarray);
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with string", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonarray[0],
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with string", json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with string",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonarray_const[0],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with string",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("object")
|
SECTION("object")
|
||||||
{
|
{
|
||||||
json j_nonarray(json::value_t::object);
|
json j_nonarray(json::value_t::object);
|
||||||
const json j_nonarray_const(j_nonarray);
|
const json j_nonarray_const(j_nonarray);
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with object", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonarray[0],
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with object", json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with object",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonarray_const[0],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with object",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("number (integer)")
|
SECTION("number (integer)")
|
||||||
{
|
{
|
||||||
json j_nonarray(json::value_t::number_integer);
|
json j_nonarray(json::value_t::number_integer);
|
||||||
const json j_nonarray_const(j_nonarray);
|
const json j_nonarray_const(j_nonarray);
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonarray[0],
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonarray_const[0],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("number (unsigned)")
|
SECTION("number (unsigned)")
|
||||||
{
|
{
|
||||||
json j_nonarray(json::value_t::number_unsigned);
|
json j_nonarray(json::value_t::number_unsigned);
|
||||||
const json j_nonarray_const(j_nonarray);
|
const json j_nonarray_const(j_nonarray);
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonarray[0],
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonarray_const[0],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("number (floating-point)")
|
SECTION("number (floating-point)")
|
||||||
{
|
{
|
||||||
json j_nonarray(json::value_t::number_float);
|
json j_nonarray(json::value_t::number_float);
|
||||||
const json j_nonarray_const(j_nonarray);
|
const json j_nonarray_const(j_nonarray);
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonarray[0],
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray_const[0], "[json.exception.type_error.305] cannot use operator[] with a numeric argument with number", json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonarray_const[0],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a numeric argument with number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -359,26 +383,34 @@ TEST_CASE("element access 1")
|
|||||||
json jarray2 = { "foo", "bar" };
|
json jarray2 = { "foo", "bar" };
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.begin()),
|
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.begin()),
|
||||||
"[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.202] iterator does not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jarray.erase(jarray.begin(), jarray2.end()),
|
CHECK_THROWS_WITH_AS(jarray.erase(jarray.begin(), jarray2.end()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.begin(), jarray.end()),
|
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.begin(), jarray.end()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.begin(), jarray2.end()),
|
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.begin(), jarray2.end()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json jarray = { 1, 1u, true, nullptr, "string", 42.23, json::object(), { 1, 2, 3 } };
|
json jarray = { 1, 1u, true, nullptr, "string", 42.23, json::object(), { 1, 2, 3 } };
|
||||||
json const jarray2 = { "foo", "bar" };
|
json const jarray2 = { "foo", "bar" };
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.cbegin()),
|
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.cbegin()),
|
||||||
"[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.202] iterator does not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jarray.erase(jarray.cbegin(), jarray2.cend()),
|
CHECK_THROWS_WITH_AS(jarray.erase(jarray.cbegin(), jarray2.cend()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.cbegin(), jarray.cend()),
|
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.cbegin(), jarray.cend()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()),
|
CHECK_THROWS_WITH_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,8 +561,7 @@ TEST_CASE("element access 1")
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
json j;
|
json j;
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.begin()),
|
CHECK_THROWS_WITH_AS(j.erase(j.begin()), "[json.exception.type_error.307] cannot use erase() with null", json::type_error&);
|
||||||
"[json.exception.type_error.307] cannot use erase() with null", json::type_error&);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -812,12 +843,16 @@ TEST_CASE("element access 1")
|
|||||||
{
|
{
|
||||||
json j = "foo";
|
json j = "foo";
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json j = "bar";
|
json j = "bar";
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -826,12 +861,16 @@ TEST_CASE("element access 1")
|
|||||||
{
|
{
|
||||||
json j = false;
|
json j = false;
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json j = true;
|
json j = true;
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -840,12 +879,16 @@ TEST_CASE("element access 1")
|
|||||||
{
|
{
|
||||||
json j = 17;
|
json j = 17;
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json j = 17;
|
json j = 17;
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -854,12 +897,16 @@ TEST_CASE("element access 1")
|
|||||||
{
|
{
|
||||||
json j = 17u;
|
json j = 17u;
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json j = 17u;
|
json j = 17u;
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -868,12 +915,16 @@ TEST_CASE("element access 1")
|
|||||||
{
|
{
|
||||||
json j = 23.42;
|
json j = 23.42;
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.begin(), j.begin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
json j = 23.42;
|
json j = 23.42;
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.erase(j.cbegin(), j.cbegin()),
|
||||||
|
"[json.exception.invalid_iterator.204] iterators out of range",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+359
-160
@@ -21,7 +21,8 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
SECTION("object")
|
SECTION("object")
|
||||||
{
|
{
|
||||||
Json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", Json::object()}, {"array", {1, 2, 3}}};
|
Json j = { { "integer", 1 }, { "unsigned", 1u }, { "floating", 42.23 }, { "null", nullptr }, { "string", "hello world" },
|
||||||
|
{ "boolean", true }, { "object", Json::object() }, { "array", { 1, 2, 3 } } };
|
||||||
const Json j_const = j;
|
const Json j_const = j;
|
||||||
|
|
||||||
SECTION("access specified element with bounds checking")
|
SECTION("access specified element with bounds checking")
|
||||||
@@ -74,7 +75,9 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j.at(std::string_view("foo")), "[json.exception.out_of_range.403] key 'foo' not found", typename Json::out_of_range&);
|
CHECK_THROWS_WITH_AS(j.at(std::string_view("foo")), "[json.exception.out_of_range.403] key 'foo' not found", typename Json::out_of_range&);
|
||||||
CHECK_THROWS_WITH_AS(j_const.at(std::string_view("foo")), "[json.exception.out_of_range.403] key 'foo' not found", typename Json::out_of_range&);
|
CHECK_THROWS_WITH_AS(j_const.at(std::string_view("foo")),
|
||||||
|
"[json.exception.out_of_range.403] key 'foo' not found",
|
||||||
|
typename Json::out_of_range&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +91,12 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view(std::string_view("foo"))), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view(std::string_view("foo"))),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view(std::string_view("foo"))), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&);
|
"[json.exception.type_error.304] cannot use at() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view(std::string_view("foo"))),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,11 +105,17 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json j_nonobject(Json::value_t::boolean);
|
Json j_nonobject(Json::value_t::boolean);
|
||||||
const Json j_nonobject_const(j_nonobject);
|
const Json j_nonobject_const(j_nonobject);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&);
|
"[json.exception.type_error.304] cannot use at() with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,11 +124,17 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json j_nonobject(Json::value_t::string);
|
Json j_nonobject(Json::value_t::string);
|
||||||
const Json j_nonobject_const(j_nonobject);
|
const Json j_nonobject_const(j_nonobject);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with string",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&);
|
"[json.exception.type_error.304] cannot use at() with string",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with string",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,8 +146,12 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&);
|
"[json.exception.type_error.304] cannot use at() with array",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with array",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,11 +160,17 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json j_nonobject(Json::value_t::number_integer);
|
Json j_nonobject(Json::value_t::number_integer);
|
||||||
const Json j_nonobject_const(j_nonobject);
|
const Json j_nonobject_const(j_nonobject);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
"[json.exception.type_error.304] cannot use at() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,11 +179,17 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json j_nonobject(Json::value_t::number_unsigned);
|
Json j_nonobject(Json::value_t::number_unsigned);
|
||||||
const Json j_nonobject_const(j_nonobject);
|
const Json j_nonobject_const(j_nonobject);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
"[json.exception.type_error.304] cannot use at() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,11 +198,17 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json j_nonobject(Json::value_t::number_float);
|
Json j_nonobject(Json::value_t::number_float);
|
||||||
const Json j_nonobject_const(j_nonobject);
|
const Json j_nonobject_const(j_nonobject);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&);
|
"[json.exception.type_error.304] cannot use at() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.304] cannot use at() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,12 +316,20 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::null);
|
Json j_nonobject(Json::value_t::null);
|
||||||
const Json j_nonobject_const(Json::value_t::null);
|
const Json j_nonobject_const(Json::value_t::null);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,12 +337,20 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::boolean);
|
Json j_nonobject(Json::value_t::boolean);
|
||||||
const Json j_nonobject_const(Json::value_t::boolean);
|
const Json j_nonobject_const(Json::value_t::boolean);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,12 +358,20 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::string);
|
Json j_nonobject(Json::value_t::string);
|
||||||
const Json j_nonobject_const(Json::value_t::string);
|
const Json j_nonobject_const(Json::value_t::string);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with string",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with string",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with string",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with string",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,12 +379,20 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::array);
|
Json j_nonobject(Json::value_t::array);
|
||||||
const Json j_nonobject_const(Json::value_t::array);
|
const Json j_nonobject_const(Json::value_t::array);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with array",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with array",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with array",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with array",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,12 +400,20 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::number_integer);
|
Json j_nonobject(Json::value_t::number_integer);
|
||||||
const Json j_nonobject_const(Json::value_t::number_integer);
|
const Json j_nonobject_const(Json::value_t::number_integer);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,12 +421,20 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::number_unsigned);
|
Json j_nonobject(Json::value_t::number_unsigned);
|
||||||
const Json j_nonobject_const(Json::value_t::number_unsigned);
|
const Json j_nonobject_const(Json::value_t::number_unsigned);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,12 +442,20 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::number_float);
|
Json j_nonobject(Json::value_t::number_float);
|
||||||
const Json j_nonobject_const(Json::value_t::number_float);
|
const Json j_nonobject_const(Json::value_t::number_float);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -400,65 +497,90 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::null);
|
Json j_nonobject(Json::value_t::null);
|
||||||
const Json j_nonobject_const(Json::value_t::null);
|
const Json j_nonobject_const(Json::value_t::null);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("boolean")
|
SECTION("boolean")
|
||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::boolean);
|
Json j_nonobject(Json::value_t::boolean);
|
||||||
const Json j_nonobject_const(Json::value_t::boolean);
|
const Json j_nonobject_const(Json::value_t::boolean);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("string")
|
SECTION("string")
|
||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::string);
|
Json j_nonobject(Json::value_t::string);
|
||||||
const Json j_nonobject_const(Json::value_t::string);
|
const Json j_nonobject_const(Json::value_t::string);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with string",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with string",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("array")
|
SECTION("array")
|
||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::array);
|
Json j_nonobject(Json::value_t::array);
|
||||||
const Json j_nonobject_const(Json::value_t::array);
|
const Json j_nonobject_const(Json::value_t::array);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with array",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with array",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("number (integer)")
|
SECTION("number (integer)")
|
||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::number_integer);
|
Json j_nonobject(Json::value_t::number_integer);
|
||||||
const Json j_nonobject_const(Json::value_t::number_integer);
|
const Json j_nonobject_const(Json::value_t::number_integer);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("number (unsigned)")
|
SECTION("number (unsigned)")
|
||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::number_unsigned);
|
Json j_nonobject(Json::value_t::number_unsigned);
|
||||||
const Json j_nonobject_const(Json::value_t::number_unsigned);
|
const Json j_nonobject_const(Json::value_t::number_unsigned);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("number (floating-point)")
|
SECTION("number (floating-point)")
|
||||||
{
|
{
|
||||||
Json j_nonobject(Json::value_t::number_float);
|
Json j_nonobject(Json::value_t::number_float);
|
||||||
const Json j_nonobject_const(Json::value_t::number_float);
|
const Json j_nonobject_const(Json::value_t::number_float);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1),
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("non-const operator[]")
|
SECTION("non-const operator[]"){ { Json j_null;
|
||||||
{
|
|
||||||
{
|
|
||||||
Json j_null;
|
|
||||||
CHECK(j_null.is_null());
|
CHECK(j_null.is_null());
|
||||||
j_null["key"] = 1;
|
j_null["key"] = 1;
|
||||||
CHECK(j_null.is_object());
|
CHECK(j_null.is_object());
|
||||||
@@ -612,12 +734,18 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
|
|
||||||
CHECK_NOTHROW(j_nonobject["foo"]);
|
CHECK_NOTHROW(j_nonobject["foo"]);
|
||||||
CHECK_NOTHROW(j_nonobject2[typename Json::object_t::key_type("foo")]);
|
CHECK_NOTHROW(j_nonobject2[typename Json::object_t::key_type("foo")]);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_NOTHROW(j_nonobject2[std::string_view("foo")]);
|
CHECK_NOTHROW(j_nonobject2[std::string_view("foo")]);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with null",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,17 +754,25 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json j_nonobject(Json::value_t::boolean);
|
Json j_nonobject(Json::value_t::boolean);
|
||||||
const Json j_const_nonobject(j_nonobject);
|
const Json j_const_nonobject(j_nonobject);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")],
|
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")],
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -645,17 +781,25 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json j_nonobject(Json::value_t::string);
|
Json j_nonobject(Json::value_t::string);
|
||||||
const Json j_const_nonobject(j_nonobject);
|
const Json j_const_nonobject(j_nonobject);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with string",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")],
|
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with string",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with string",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with string",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")],
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with string",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with string",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -664,16 +808,25 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json j_nonobject(Json::value_t::array);
|
Json j_nonobject(Json::value_t::array);
|
||||||
const Json j_const_nonobject(j_nonobject);
|
const Json j_const_nonobject(j_nonobject);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with array",
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&);
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with array",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with array",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with array",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")],
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with array",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with array",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,17 +835,25 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json j_nonobject(Json::value_t::number_integer);
|
Json j_nonobject(Json::value_t::number_integer);
|
||||||
const Json j_const_nonobject(j_nonobject);
|
const Json j_const_nonobject(j_nonobject);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")],
|
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")],
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,17 +862,25 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json j_nonobject(Json::value_t::number_unsigned);
|
Json j_nonobject(Json::value_t::number_unsigned);
|
||||||
const Json j_const_nonobject(j_nonobject);
|
const Json j_const_nonobject(j_nonobject);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")],
|
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")],
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,17 +889,25 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json j_nonobject(Json::value_t::number_float);
|
Json j_nonobject(Json::value_t::number_float);
|
||||||
const Json j_const_nonobject(j_nonobject);
|
const Json j_const_nonobject(j_nonobject);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")],
|
CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
CHECK_THROWS_WITH_AS(j_const_nonobject["foo"],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")],
|
||||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")],
|
||||||
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&);
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")],
|
||||||
|
"[json.exception.type_error.305] cannot use operator[] with a string argument with number",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -916,25 +1093,33 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
Json jobject = { { "a", "a" }, { "b", 1 }, { "c", 17u }, { "d", false }, { "e", true } };
|
Json jobject = { { "a", "a" }, { "b", 1 }, { "c", 17u }, { "d", false }, { "e", true } };
|
||||||
Json jobject2 = { { "a", "a" }, { "b", 1 }, { "c", 17u } };
|
Json jobject2 = { { "a", "a" }, { "b", 1 }, { "c", 17u } };
|
||||||
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin()),
|
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin()),
|
||||||
"[json.exception.invalid_iterator.202] iterator does not fit current value", typename Json::invalid_iterator&);
|
"[json.exception.invalid_iterator.202] iterator does not fit current value",
|
||||||
|
typename Json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jobject.erase(jobject.begin(), jobject2.end()),
|
CHECK_THROWS_WITH_AS(jobject.erase(jobject.begin(), jobject2.end()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
typename Json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin(), jobject.end()),
|
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin(), jobject.end()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
typename Json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin(), jobject2.end()),
|
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin(), jobject2.end()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
typename Json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Json jobject = { { "a", "a" }, { "b", 1 }, { "c", 17u }, { "d", false }, { "e", true } };
|
Json jobject = { { "a", "a" }, { "b", 1 }, { "c", 17u }, { "d", false }, { "e", true } };
|
||||||
Json jobject2 = { { "a", "a" }, { "b", 1 }, { "c", 17u } };
|
Json jobject2 = { { "a", "a" }, { "b", 1 }, { "c", 17u } };
|
||||||
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin()),
|
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin()),
|
||||||
"[json.exception.invalid_iterator.202] iterator does not fit current value", typename Json::invalid_iterator&);
|
"[json.exception.invalid_iterator.202] iterator does not fit current value",
|
||||||
|
typename Json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jobject.erase(jobject.cbegin(), jobject2.cend()),
|
CHECK_THROWS_WITH_AS(jobject.erase(jobject.cbegin(), jobject2.cend()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
typename Json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin(), jobject.cend()),
|
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin(), jobject.cend()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
typename Json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()),
|
CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()),
|
||||||
"[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&);
|
"[json.exception.invalid_iterator.203] iterators do not fit current value",
|
||||||
|
typename Json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -947,7 +1132,9 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with null", typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.307] cannot use erase() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -957,7 +1144,9 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with boolean", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with boolean", typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with boolean", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.307] cannot use erase() with boolean",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,7 +1156,9 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with string", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with string", typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with string", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.307] cannot use erase() with string",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -977,7 +1168,9 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with array", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with array", typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with array", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.307] cannot use erase() with array",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -987,7 +1180,9 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.307] cannot use erase() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -997,7 +1192,9 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&);
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")),
|
||||||
|
"[json.exception.type_error.307] cannot use erase() with number",
|
||||||
|
typename Json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1007,9 +1204,7 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
SECTION("existing element")
|
SECTION("existing element")
|
||||||
{
|
{
|
||||||
for (const auto* key :
|
for (const auto* key : { "integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" })
|
||||||
{"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CHECK(j.find(key) != j.end());
|
CHECK(j.find(key) != j.end());
|
||||||
CHECK(*j.find(key) == j.at(key));
|
CHECK(*j.find(key) == j.at(key));
|
||||||
@@ -1017,9 +1212,7 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
CHECK(*j_const.find(key) == j_const.at(key));
|
CHECK(*j_const.find(key) == j_const.at(key));
|
||||||
}
|
}
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
for (const std::string_view key :
|
for (const std::string_view key : { "integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" })
|
||||||
{"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CHECK(j.find(key) != j.end());
|
CHECK(j.find(key) != j.end());
|
||||||
CHECK(*j.find(key) == j.at(key));
|
CHECK(*j.find(key) == j.at(key));
|
||||||
@@ -1160,17 +1353,13 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
SECTION("existing element")
|
SECTION("existing element")
|
||||||
{
|
{
|
||||||
for (const auto* key :
|
for (const auto* key : { "integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" })
|
||||||
{"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CHECK(j.count(key) == 1);
|
CHECK(j.count(key) == 1);
|
||||||
CHECK(j_const.count(key) == 1);
|
CHECK(j_const.count(key) == 1);
|
||||||
}
|
}
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
for (const std::string_view key :
|
for (const std::string_view key : { "integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" })
|
||||||
{"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CHECK(j.count(key) == 1);
|
CHECK(j.count(key) == 1);
|
||||||
CHECK(j_const.count(key) == 1);
|
CHECK(j_const.count(key) == 1);
|
||||||
@@ -1309,18 +1498,14 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
{
|
{
|
||||||
SECTION("existing element")
|
SECTION("existing element")
|
||||||
{
|
{
|
||||||
for (const auto* key :
|
for (const auto* key : { "integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" })
|
||||||
{"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CHECK(j.contains(key) == true);
|
CHECK(j.contains(key) == true);
|
||||||
CHECK(j_const.contains(key) == true);
|
CHECK(j_const.contains(key) == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
for (const std::string_view key :
|
for (const std::string_view key : { "integer", "unsigned", "floating", "null", "string", "boolean", "object", "array" })
|
||||||
{"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CHECK(j.contains(key) == true);
|
CHECK(j.contains(key) == true);
|
||||||
CHECK(j_const.contains(key) == true);
|
CHECK(j_const.contains(key) == true);
|
||||||
@@ -1460,8 +1645,10 @@ TEST_CASE_TEMPLATE("element access 2 (throwing tests)", Json, nlohmann::json, nl
|
|||||||
{
|
{
|
||||||
SECTION("object")
|
SECTION("object")
|
||||||
{
|
{
|
||||||
Json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", Json::object()}, {"array", {1, 2, 3}}};
|
Json j = { { "integer", 1 }, { "unsigned", 1u }, { "floating", 42.23 }, { "null", nullptr }, { "string", "hello world" },
|
||||||
const Json j_const = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", Json::object()}, {"array", {1, 2, 3}}};
|
{ "boolean", true }, { "object", Json::object() }, { "array", { 1, 2, 3 } } };
|
||||||
|
const Json j_const = { { "integer", 1 }, { "unsigned", 1u }, { "floating", 42.23 }, { "null", nullptr }, { "string", "hello world" },
|
||||||
|
{ "boolean", true }, { "object", Json::object() }, { "array", { 1, 2, 3 } } };
|
||||||
|
|
||||||
SECTION("access specified element with default value")
|
SECTION("access specified element with default value")
|
||||||
{
|
{
|
||||||
@@ -1500,11 +1687,7 @@ TEST_CASE_TEMPLATE("element access 2 (additional value() tests)", Json, nlohmann
|
|||||||
// test assumes string_t and object_t::key_type are the same
|
// test assumes string_t and object_t::key_type are the same
|
||||||
REQUIRE(std::is_same<string_t, typename Json::object_t::key_type>::value);
|
REQUIRE(std::is_same<string_t, typename Json::object_t::key_type>::value);
|
||||||
|
|
||||||
Json j
|
Json j{ { "foo", "bar" }, { "baz", 42 } };
|
||||||
{
|
|
||||||
{"foo", "bar"},
|
|
||||||
{"baz", 42}
|
|
||||||
};
|
|
||||||
|
|
||||||
const char* cpstr = "default";
|
const char* cpstr = "default";
|
||||||
const char castr[] = "default"; // NOLINT(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays)
|
const char castr[] = "default"; // NOLINT(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays)
|
||||||
@@ -1513,11 +1696,7 @@ TEST_CASE_TEMPLATE("element access 2 (additional value() tests)", Json, nlohmann
|
|||||||
number_integer_t integer = 69;
|
number_integer_t integer = 69;
|
||||||
std::size_t size = 69;
|
std::size_t size = 69;
|
||||||
|
|
||||||
SECTION("deduced ValueType")
|
SECTION("deduced ValueType"){ SECTION("literal key"){ CHECK(j.value("foo", "default") == "bar");
|
||||||
{
|
|
||||||
SECTION("literal key")
|
|
||||||
{
|
|
||||||
CHECK(j.value("foo", "default") == "bar");
|
|
||||||
CHECK(j.value("foo", cpstr) == "bar");
|
CHECK(j.value("foo", cpstr) == "bar");
|
||||||
CHECK(j.value("foo", castr) == "bar");
|
CHECK(j.value("foo", castr) == "bar");
|
||||||
CHECK(j.value("foo", str) == "bar");
|
CHECK(j.value("foo", str) == "bar");
|
||||||
@@ -1665,8 +1844,12 @@ TEST_CASE_TEMPLATE("element access 2 (additional value() tests)", Json, nlohmann
|
|||||||
CHECK(j.template value<std::size_t>("bar", 47) == 47);
|
CHECK(j.template value<std::size_t>("bar", 47) == 47);
|
||||||
CHECK(j.template value<std::size_t>("bar", size) == size);
|
CHECK(j.template value<std::size_t>("bar", size) == size);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(Json().template value<string_t>("foo", "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(Json().template value<string_t>("foo", "default"),
|
||||||
CHECK_THROWS_WITH_AS(Json().template value<string_t>("foo", str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(Json().template value<string_t>("foo", str),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("const char * key")
|
SECTION("const char * key")
|
||||||
@@ -1694,8 +1877,12 @@ TEST_CASE_TEMPLATE("element access 2 (additional value() tests)", Json, nlohmann
|
|||||||
CHECK(j.template value<std::size_t>(key_notfound, 47) == 47);
|
CHECK(j.template value<std::size_t>(key_notfound, 47) == 47);
|
||||||
CHECK(j.template value<std::size_t>(key_notfound, size) == size);
|
CHECK(j.template value<std::size_t>(key_notfound, size) == size);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"),
|
||||||
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("const char(&)[] key")
|
SECTION("const char(&)[] key")
|
||||||
@@ -1723,8 +1910,12 @@ TEST_CASE_TEMPLATE("element access 2 (additional value() tests)", Json, nlohmann
|
|||||||
CHECK(j.template value<std::size_t>(key_notfound, 47) == 47);
|
CHECK(j.template value<std::size_t>(key_notfound, 47) == 47);
|
||||||
CHECK(j.template value<std::size_t>(key_notfound, size) == size);
|
CHECK(j.template value<std::size_t>(key_notfound, size) == size);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"),
|
||||||
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("string_t/object_t::key_type key")
|
SECTION("string_t/object_t::key_type key")
|
||||||
@@ -1748,8 +1939,12 @@ TEST_CASE_TEMPLATE("element access 2 (additional value() tests)", Json, nlohmann
|
|||||||
CHECK(j.template value<std::size_t>(key_notfound, 0) == 0);
|
CHECK(j.template value<std::size_t>(key_notfound, 0) == 0);
|
||||||
CHECK(j.template value<std::size_t>(key_notfound, 47) == 47);
|
CHECK(j.template value<std::size_t>(key_notfound, 47) == 47);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"),
|
||||||
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
@@ -1785,8 +1980,12 @@ TEST_CASE_TEMPLATE("element access 2 (additional value() tests)", Json, nlohmann
|
|||||||
|
|
||||||
CHECK(j.template value<std::string_view>(key_notfound, "default") == "default");
|
CHECK(j.template value<std::string_view>(key_notfound, "default") == "default");
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, "default"),
|
||||||
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&);
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(Json().template value<string_t>(key, str),
|
||||||
|
"[json.exception.type_error.306] cannot use value() with null",
|
||||||
|
typename Json::type_error&);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
|
#include "make_test_data_available.hpp"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "make_test_data_available.hpp"
|
|
||||||
|
|
||||||
TEST_CASE("object inspection")
|
TEST_CASE("object inspection")
|
||||||
{
|
{
|
||||||
@@ -202,12 +202,12 @@ TEST_CASE("object inspection")
|
|||||||
|
|
||||||
SECTION("serialization")
|
SECTION("serialization")
|
||||||
{
|
{
|
||||||
json const j {{"object", json::object()}, {"array", {1, 2, 3, 4}}, {"number", 42}, {"boolean", false}, {"null", nullptr}, {"string", "Hello world"} };
|
json const j{ { "object", json::object() }, { "array", { 1, 2, 3, 4 } }, { "number", 42 },
|
||||||
|
{ "boolean", false }, { "null", nullptr }, { "string", "Hello world" } };
|
||||||
|
|
||||||
SECTION("no indent / indent=-1")
|
SECTION("no indent / indent=-1")
|
||||||
{
|
{
|
||||||
CHECK(j.dump() ==
|
CHECK(j.dump() == "{\"array\":[1,2,3,4],\"boolean\":false,\"null\":null,\"number\":42,\"object\":{},\"string\":\"Hello world\"}");
|
||||||
"{\"array\":[1,2,3,4],\"boolean\":false,\"null\":null,\"number\":42,\"object\":{},\"string\":\"Hello world\"}");
|
|
||||||
|
|
||||||
CHECK(j.dump() == j.dump(-1));
|
CHECK(j.dump() == j.dump(-1));
|
||||||
}
|
}
|
||||||
@@ -220,13 +220,15 @@ TEST_CASE("object inspection")
|
|||||||
|
|
||||||
SECTION("indent=1, space='\t'")
|
SECTION("indent=1, space='\t'")
|
||||||
{
|
{
|
||||||
CHECK(j.dump(1, '\t') ==
|
CHECK(
|
||||||
|
j.dump(1, '\t') ==
|
||||||
"{\n\t\"array\": [\n\t\t1,\n\t\t2,\n\t\t3,\n\t\t4\n\t],\n\t\"boolean\": false,\n\t\"null\": null,\n\t\"number\": 42,\n\t\"object\": {},\n\t\"string\": \"Hello world\"\n}");
|
"{\n\t\"array\": [\n\t\t1,\n\t\t2,\n\t\t3,\n\t\t4\n\t],\n\t\"boolean\": false,\n\t\"null\": null,\n\t\"number\": 42,\n\t\"object\": {},\n\t\"string\": \"Hello world\"\n}");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("indent=4")
|
SECTION("indent=4")
|
||||||
{
|
{
|
||||||
CHECK(j.dump(4) ==
|
CHECK(
|
||||||
|
j.dump(4) ==
|
||||||
"{\n \"array\": [\n 1,\n 2,\n 3,\n 4\n ],\n \"boolean\": false,\n \"null\": null,\n \"number\": 42,\n \"object\": {},\n \"string\": \"Hello world\"\n}");
|
"{\n \"array\": [\n 1,\n 2,\n 3,\n 4\n ],\n \"boolean\": false,\n \"null\": null,\n \"number\": 42,\n \"object\": {},\n \"string\": \"Hello world\"\n}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,8 +293,7 @@ TEST_CASE("object inspection")
|
|||||||
json const value = json::parse(f_unescaped);
|
json const value = json::parse(f_unescaped);
|
||||||
std::string text = value.dump(4, ' ', true);
|
std::string text = value.dump(4, ' ', true);
|
||||||
|
|
||||||
std::string expected((std::istreambuf_iterator<char>(f_escaped)),
|
std::string expected((std::istreambuf_iterator<char>(f_escaped)), std::istreambuf_iterator<char>());
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
CHECK(text == expected);
|
CHECK(text == expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,9 +329,7 @@ TEST_CASE("object inspection")
|
|||||||
|
|
||||||
SECTION("round trips")
|
SECTION("round trips")
|
||||||
{
|
{
|
||||||
for (const auto& s :
|
for (const auto& s : { "3.141592653589793", "1000000000000000010E5" })
|
||||||
{"3.141592653589793", "1000000000000000010E5"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
json const j1 = json::parse(s);
|
json const j1 = json::parse(s);
|
||||||
std::string s1 = j1.dump();
|
std::string s1 = j1.dump();
|
||||||
|
|||||||
@@ -718,11 +718,7 @@ TEST_CASE("iterator_wrapper")
|
|||||||
|
|
||||||
TEST_CASE("items()")
|
TEST_CASE("items()")
|
||||||
{
|
{
|
||||||
SECTION("object")
|
SECTION("object"){ SECTION("value"){ json j = { { "A", 1 }, { "B", 2 } };
|
||||||
{
|
|
||||||
SECTION("value")
|
|
||||||
{
|
|
||||||
json j = { {"A", 1}, {"B", 2} };
|
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
|
||||||
for (auto i : j.items()) // NOLINT(performance-for-range-copy)
|
for (auto i : j.items()) // NOLINT(performance-for-range-copy)
|
||||||
|
|||||||
+316
-112
@@ -74,23 +74,47 @@ TEST_CASE("iterators 2")
|
|||||||
if (j.type() == json::value_t::object)
|
if (j.type() == json::value_t::object)
|
||||||
{
|
{
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(it1 < it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 < it1,
|
||||||
CHECK_THROWS_WITH_AS(it1 < it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 < it2,
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 < it3,
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1 < it3,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c < it1_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c < it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c < it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c < it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(it1 < it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 < it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 < it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 < it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c < it1_c,
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c < it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c < it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c < it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -111,23 +135,47 @@ TEST_CASE("iterators 2")
|
|||||||
if (j.type() == json::value_t::object)
|
if (j.type() == json::value_t::object)
|
||||||
{
|
{
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 <= it1,
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 <= it2,
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 <= it3,
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1 <= it3,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c <= it1_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c <= it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c <= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c <= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 <= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 <= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c <= it1_c,
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c <= it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c <= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c <= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -149,23 +197,47 @@ TEST_CASE("iterators 2")
|
|||||||
if (j.type() == json::value_t::object)
|
if (j.type() == json::value_t::object)
|
||||||
{
|
{
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(it1 > it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 > it1,
|
||||||
CHECK_THROWS_WITH_AS(it1 > it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 > it2,
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 > it3,
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1 > it3,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c > it1_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c > it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c > it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c > it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(it1 > it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 > it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 > it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 > it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c > it1_c,
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c > it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c > it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c > it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -187,23 +259,47 @@ TEST_CASE("iterators 2")
|
|||||||
if (j.type() == json::value_t::object)
|
if (j.type() == json::value_t::object)
|
||||||
{
|
{
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 >= it1,
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 >= it2,
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 >= it3,
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1 >= it3,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c >= it1_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c >= it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c >= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c >= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 >= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 >= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c >= it1_c,
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c >= it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c >= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c >= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -231,10 +327,18 @@ TEST_CASE("iterators 2")
|
|||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
// the output differs in each loop, so we cannot fix a string for the expected exception
|
// the output differs in each loop, so we cannot fix a string for the expected exception
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.begin() == k.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.begin() == k.begin(),
|
||||||
CHECK_THROWS_WITH_AS(j.cbegin() == k.cbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers",
|
||||||
CHECK_THROWS_WITH_AS(j.begin() < k.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.cbegin() < k.cbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.cbegin() == k.cbegin(),
|
||||||
|
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(j.begin() < k.begin(),
|
||||||
|
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(j.cbegin() < k.cbegin(),
|
||||||
|
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers",
|
||||||
|
json::invalid_iterator&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -498,23 +602,47 @@ TEST_CASE("iterators 2")
|
|||||||
if (j.type() == json::value_t::object)
|
if (j.type() == json::value_t::object)
|
||||||
{
|
{
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(it1 < it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 < it1,
|
||||||
CHECK_THROWS_WITH_AS(it1 < it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 < it2,
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 < it3,
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1 < it3,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c < it1_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c < it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c < it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c < it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(it1 < it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 < it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 < it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 < it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c < it1_c,
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c < it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c < it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c < it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -535,23 +663,47 @@ TEST_CASE("iterators 2")
|
|||||||
if (j.type() == json::value_t::object)
|
if (j.type() == json::value_t::object)
|
||||||
{
|
{
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 <= it1,
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 <= it2,
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 <= it3,
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1 <= it3,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c <= it1_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c <= it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c <= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c <= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 <= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 <= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c <= it1_c,
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c <= it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c <= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c <= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -573,23 +725,47 @@ TEST_CASE("iterators 2")
|
|||||||
if (j.type() == json::value_t::object)
|
if (j.type() == json::value_t::object)
|
||||||
{
|
{
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(it1 > it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 > it1,
|
||||||
CHECK_THROWS_WITH_AS(it1 > it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 > it2,
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 > it3,
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1 > it3,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c > it1_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c > it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c > it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c > it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(it1 > it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 > it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 > it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 > it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c > it1_c,
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c > it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c > it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c > it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -611,23 +787,47 @@ TEST_CASE("iterators 2")
|
|||||||
if (j.type() == json::value_t::object)
|
if (j.type() == json::value_t::object)
|
||||||
{
|
{
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 >= it1,
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 >= it2,
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 >= it3,
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1 >= it3,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c >= it1_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c >= it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c >= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c >= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 >= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 >= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it2 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it2 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it1_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c >= it1_c,
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
CHECK_THROWS_WITH_AS(it2_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(it1_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(it1_c >= it2_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it2_c >= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(it1_c >= it3_c,
|
||||||
|
"[json.exception.invalid_iterator.213] cannot compare order of object iterators",
|
||||||
|
json::invalid_iterator&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -655,10 +855,18 @@ TEST_CASE("iterators 2")
|
|||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
// the output differs in each loop, so we cannot fix a string for the expected exception
|
// the output differs in each loop, so we cannot fix a string for the expected exception
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.rbegin() == k.rbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.rbegin() == k.rbegin(),
|
||||||
CHECK_THROWS_WITH_AS(j.crbegin() == k.crbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers",
|
||||||
CHECK_THROWS_WITH_AS(j.rbegin() < k.rbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j.crbegin() < k.crbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j.crbegin() == k.crbegin(),
|
||||||
|
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(j.rbegin() < k.rbegin(),
|
||||||
|
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(j.crbegin() < k.crbegin(),
|
||||||
|
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers",
|
||||||
|
json::invalid_iterator&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -913,13 +1121,11 @@ TEST_CASE("iterators 2")
|
|||||||
auto j_even = json::array();
|
auto j_even = json::array();
|
||||||
|
|
||||||
#if JSON_USE_IMPLICIT_CONVERSIONS
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
auto it = std::ranges::find_if(j, [](int v) noexcept
|
auto it = std::ranges::find_if(j, [](int v) noexcept {
|
||||||
{
|
|
||||||
return (v % 2) == 0;
|
return (v % 2) == 0;
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
auto it = std::ranges::find_if(j, [](const json & j) noexcept
|
auto it = std::ranges::find_if(j, [](const json& j) noexcept {
|
||||||
{
|
|
||||||
int v;
|
int v;
|
||||||
j.get_to(v);
|
j.get_to(v);
|
||||||
return (v % 2) == 0;
|
return (v % 2) == 0;
|
||||||
@@ -947,16 +1153,14 @@ TEST_CASE("iterators 2")
|
|||||||
|
|
||||||
SECTION("transform")
|
SECTION("transform")
|
||||||
{
|
{
|
||||||
json j
|
json j{
|
||||||
{
|
|
||||||
{ "a_key", "a_value" },
|
{ "a_key", "a_value" },
|
||||||
{ "b_key", "b_value" },
|
{ "b_key", "b_value" },
|
||||||
{ "c_key", "c_value" },
|
{ "c_key", "c_value" },
|
||||||
};
|
};
|
||||||
json j_expected{ "a_key", "b_key", "c_key" };
|
json j_expected{ "a_key", "b_key", "c_key" };
|
||||||
|
|
||||||
auto transformed = j.items() | std::views::transform([](const auto & item)
|
auto transformed = j.items() | std::views::transform([](const auto& item) {
|
||||||
{
|
|
||||||
return item.key();
|
return item.key();
|
||||||
});
|
});
|
||||||
auto j_transformed = json::array();
|
auto j_transformed = json::array();
|
||||||
|
|||||||
+145
-84
@@ -14,8 +14,8 @@ using nlohmann::json;
|
|||||||
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
|
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
TEST_CASE("JSON patch")
|
TEST_CASE("JSON patch")
|
||||||
{
|
{
|
||||||
@@ -667,7 +667,9 @@ TEST_CASE("JSON patch")
|
|||||||
{
|
{
|
||||||
json const j;
|
json const j;
|
||||||
json const patch = { { "op", "add" }, { "path", "" }, { "value", 1 } };
|
json const patch = { { "op", "add" }, { "path", "" }, { "value", 1 } };
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.104] parse error: JSON patch must be an array of objects", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.104] parse error: JSON patch must be an array of objects",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("not an array of objects")
|
SECTION("not an array of objects")
|
||||||
@@ -675,9 +677,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { "op", "add", "path", "", "value", 1 };
|
json const patch = { "op", "add", "path", "", "value", 1 };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.104] parse error: (/0) JSON patch must be an array of objects", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.104] parse error: (/0) JSON patch must be an array of objects",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.104] parse error: JSON patch must be an array of objects", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.104] parse error: JSON patch must be an array of objects",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -697,9 +703,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", 1 } } };
|
json const patch = { { { "op", 1 } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation must have string member 'op'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation must have string member 'op'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation must have string member 'op'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation must have string member 'op'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -722,9 +732,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "add" } } };
|
json const patch = { { { "op", "add" } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'add' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'add' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'add' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'add' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,9 +747,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "add" }, { "path", 1 } } };
|
json const patch = { { { "op", "add" }, { "path", 1 } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'add' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'add' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'add' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'add' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,9 +762,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "add" }, { "path", "" } } };
|
json const patch = { { { "op", "add" }, { "path", "" } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'add' must have member 'value'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'add' must have member 'value'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'add' must have member 'value'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'add' must have member 'value'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -765,9 +787,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "remove" } } };
|
json const patch = { { { "op", "remove" } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'remove' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'remove' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'remove' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'remove' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -776,9 +802,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "remove" }, { "path", 1 } } };
|
json const patch = { { { "op", "remove" }, { "path", 1 } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'remove' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'remove' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'remove' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'remove' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -811,9 +841,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "replace" } } };
|
json const patch = { { { "op", "replace" } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'replace' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'replace' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -822,9 +856,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "replace" }, { "path", 1 } } };
|
json const patch = { { { "op", "replace" }, { "path", 1 } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'replace' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'replace' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -833,9 +871,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "replace" }, { "path", "" } } };
|
json const patch = { { { "op", "replace" }, { "path", "" } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have member 'value'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have member 'value'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'replace' must have member 'value'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'replace' must have member 'value'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,9 +903,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "move" } } };
|
json const patch = { { { "op", "move" } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'move' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'move' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'move' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'move' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -872,9 +918,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "move" }, { "path", 1 } } };
|
json const patch = { { { "op", "move" }, { "path", 1 } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'move' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'move' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'move' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'move' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -884,9 +934,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const patch = { { { "op", "move" }, { "path", "" } } };
|
json const patch = { { { "op", "move" }, { "path", "" } } };
|
||||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'move' must have member 'from'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'move' must have member 'from'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'move' must have member 'from'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'move' must have member 'from'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -896,9 +950,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const patch = { { { "op", "move" }, { "path", "" }, { "from", 1 } } };
|
json const patch = { { { "op", "move" }, { "path", "" }, { "from", 1 } } };
|
||||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'move' must have string member 'from'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'move' must have string member 'from'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'move' must have string member 'from'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'move' must have string member 'from'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -924,9 +982,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "copy" } } };
|
json const patch = { { { "op", "copy" } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'copy' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'copy' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -935,9 +997,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "copy" }, { "path", 1 } } };
|
json const patch = { { { "op", "copy" }, { "path", 1 } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -946,9 +1012,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "copy" }, { "path", "" } } };
|
json const patch = { { { "op", "copy" }, { "path", "" } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have member 'from'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have member 'from'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'copy' must have member 'from'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'copy' must have member 'from'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -957,9 +1027,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "copy" }, { "path", "" }, { "from", 1 } } };
|
json const patch = { { { "op", "copy" }, { "path", "" }, { "from", 1 } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have string member 'from'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have string member 'from'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -985,9 +1059,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "test" } } };
|
json const patch = { { { "op", "test" } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'test' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'test' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'test' must have member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'test' must have member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -996,9 +1074,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "test" }, { "path", 1 } } };
|
json const patch = { { { "op", "test" }, { "path", 1 } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'test' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'test' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'test' must have string member 'path'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'test' must have string member 'path'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1007,9 +1089,13 @@ TEST_CASE("JSON patch")
|
|||||||
json const j;
|
json const j;
|
||||||
json const patch = { { { "op", "test" }, { "path", "" } } };
|
json const patch = { { { "op", "test" }, { "path", "" } } };
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'test' must have member 'value'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: (/0) operation 'test' must have member 'value'",
|
||||||
|
json::parse_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'test' must have member 'value'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j.patch(patch),
|
||||||
|
"[json.exception.parse_error.105] parse error: operation 'test' must have member 'value'",
|
||||||
|
json::parse_error&);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1216,77 +1302,52 @@ TEST_CASE("JSON patch")
|
|||||||
{
|
{
|
||||||
SECTION("add")
|
SECTION("add")
|
||||||
{
|
{
|
||||||
CHECK(R"( {} )"_json.patch(
|
CHECK(R"( {} )"_json.patch(R"( [{"op": "add", "path": "/foo", "value": "bar"}] )"_json) == R"( {"foo": "bar"} )"_json);
|
||||||
R"( [{"op": "add", "path": "/foo", "value": "bar"}] )"_json
|
|
||||||
) == R"( {"foo": "bar"} )"_json);
|
|
||||||
|
|
||||||
CHECK(R"( {"foo": [1, 3]} )"_json.patch(
|
CHECK(R"( {"foo": [1, 3]} )"_json.patch(R"( [{"op": "add", "path": "/foo", "value": "bar"}] )"_json) == R"( {"foo": "bar"} )"_json);
|
||||||
R"( [{"op": "add", "path": "/foo", "value": "bar"}] )"_json
|
|
||||||
) == R"( {"foo": "bar"} )"_json);
|
|
||||||
|
|
||||||
CHECK(R"( {"foo": [{}]} )"_json.patch(
|
CHECK(R"( {"foo": [{}]} )"_json.patch(R"( [{"op": "add", "path": "/foo/0/bar", "value": "baz"}] )"_json) == R"( {"foo": [{"bar": "baz"}]} )"_json);
|
||||||
R"( [{"op": "add", "path": "/foo/0/bar", "value": "baz"}] )"_json
|
|
||||||
) == R"( {"foo": [{"bar": "baz"}]} )"_json);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("remove")
|
SECTION("remove")
|
||||||
{
|
{
|
||||||
CHECK(R"( {"foo": "bar"} )"_json.patch(
|
CHECK(R"( {"foo": "bar"} )"_json.patch(R"( [{"op": "remove", "path": "/foo"}] )"_json) == R"( {} )"_json);
|
||||||
R"( [{"op": "remove", "path": "/foo"}] )"_json
|
|
||||||
) == R"( {} )"_json);
|
|
||||||
|
|
||||||
CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(
|
CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(R"( [{"op": "remove", "path": "/foo/1"}] )"_json) == R"( {"foo": [1, 3]} )"_json);
|
||||||
R"( [{"op": "remove", "path": "/foo/1"}] )"_json
|
|
||||||
) == R"( {"foo": [1, 3]} )"_json);
|
|
||||||
|
|
||||||
CHECK(R"( {"foo": [{"bar": "baz"}]} )"_json.patch(
|
CHECK(R"( {"foo": [{"bar": "baz"}]} )"_json.patch(R"( [{"op": "remove", "path": "/foo/0/bar"}] )"_json) == R"( {"foo": [{}]} )"_json);
|
||||||
R"( [{"op": "remove", "path": "/foo/0/bar"}] )"_json
|
|
||||||
) == R"( {"foo": [{}]} )"_json);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("replace")
|
SECTION("replace")
|
||||||
{
|
{
|
||||||
CHECK(R"( {"foo": "bar"} )"_json.patch(
|
CHECK(R"( {"foo": "bar"} )"_json.patch(R"( [{"op": "replace", "path": "/foo", "value": 1}] )"_json) == R"( {"foo": 1} )"_json);
|
||||||
R"( [{"op": "replace", "path": "/foo", "value": 1}] )"_json
|
|
||||||
) == R"( {"foo": 1} )"_json);
|
|
||||||
|
|
||||||
CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(
|
CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(R"( [{"op": "replace", "path": "/foo/1", "value": 4}] )"_json) == R"( {"foo": [1, 4, 3]} )"_json);
|
||||||
R"( [{"op": "replace", "path": "/foo/1", "value": 4}] )"_json
|
|
||||||
) == R"( {"foo": [1, 4, 3]} )"_json);
|
|
||||||
|
|
||||||
CHECK(R"( {"foo": [{"bar": "baz"}]} )"_json.patch(
|
CHECK(R"( {"foo": [{"bar": "baz"}]} )"_json.patch(R"( [{"op": "replace", "path": "/foo/0/bar", "value": 1}] )"_json) ==
|
||||||
R"( [{"op": "replace", "path": "/foo/0/bar", "value": 1}] )"_json
|
R"( {"foo": [{"bar": 1}]} )"_json);
|
||||||
) == R"( {"foo": [{"bar": 1}]} )"_json);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("move")
|
SECTION("move")
|
||||||
{
|
{
|
||||||
CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(
|
CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(R"( [{"op": "move", "from": "/foo", "path": "/bar"}] )"_json) == R"( {"bar": [1, 2, 3]} )"_json);
|
||||||
R"( [{"op": "move", "from": "/foo", "path": "/bar"}] )"_json
|
|
||||||
) == R"( {"bar": [1, 2, 3]} )"_json);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("copy")
|
SECTION("copy")
|
||||||
{
|
{
|
||||||
CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(
|
CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(R"( [{"op": "copy", "from": "/foo/1", "path": "/bar"}] )"_json) ==
|
||||||
R"( [{"op": "copy", "from": "/foo/1", "path": "/bar"}] )"_json
|
R"( {"foo": [1, 2, 3], "bar": 2} )"_json);
|
||||||
) == R"( {"foo": [1, 2, 3], "bar": 2} )"_json);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("copy")
|
SECTION("copy")
|
||||||
{
|
{
|
||||||
CHECK_NOTHROW(R"( {"foo": "bar"} )"_json.patch(
|
CHECK_NOTHROW(R"( {"foo": "bar"} )"_json.patch(R"( [{"op": "test", "path": "/foo", "value": "bar"}] )"_json));
|
||||||
R"( [{"op": "test", "path": "/foo", "value": "bar"}] )"_json));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Tests from github.com/json-patch/json-patch-tests")
|
SECTION("Tests from github.com/json-patch/json-patch-tests")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { TEST_DATA_DIRECTORY "/json-patch-tests/spec_tests.json", TEST_DATA_DIRECTORY "/json-patch-tests/tests.json" })
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/json-patch-tests/spec_tests.json",
|
|
||||||
TEST_DATA_DIRECTORY "/json-patch-tests/tests.json"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
|
|||||||
+83
-125
@@ -23,26 +23,26 @@ TEST_CASE("JSON pointers")
|
|||||||
SECTION("errors")
|
SECTION("errors")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_AS(json::json_pointer("foo"),
|
CHECK_THROWS_WITH_AS(json::json_pointer("foo"),
|
||||||
"[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'", json::parse_error&);
|
"[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(json::json_pointer("/~~"),
|
CHECK_THROWS_WITH_AS(json::json_pointer("/~~"),
|
||||||
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'", json::parse_error&);
|
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(json::json_pointer("/~"),
|
CHECK_THROWS_WITH_AS(json::json_pointer("/~"),
|
||||||
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'", json::parse_error&);
|
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
json::json_pointer p;
|
json::json_pointer p;
|
||||||
CHECK_THROWS_WITH_AS(p.top(),
|
CHECK_THROWS_WITH_AS(p.top(), "[json.exception.out_of_range.405] JSON pointer has no parent", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.405] JSON pointer has no parent", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(p.pop_back(), "[json.exception.out_of_range.405] JSON pointer has no parent", json::out_of_range&);
|
||||||
CHECK_THROWS_WITH_AS(p.pop_back(),
|
|
||||||
"[json.exception.out_of_range.405] JSON pointer has no parent", json::out_of_range&);
|
|
||||||
|
|
||||||
SECTION("array index error")
|
SECTION("array index error")
|
||||||
{
|
{
|
||||||
json v = { 1, 2, 3, 4 };
|
json v = { 1, 2, 3, 4 };
|
||||||
json::json_pointer const ptr("/10e");
|
json::json_pointer const ptr("/10e");
|
||||||
CHECK_THROWS_WITH_AS(v[ptr],
|
CHECK_THROWS_WITH_AS(v[ptr], "[json.exception.out_of_range.404] unresolved reference token '10e'", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.404] unresolved reference token '10e'", json::out_of_range&);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,10 +143,10 @@ TEST_CASE("JSON pointers")
|
|||||||
|
|
||||||
// unresolved access
|
// unresolved access
|
||||||
json j_primitive = 1;
|
json j_primitive = 1;
|
||||||
CHECK_THROWS_WITH_AS(j_primitive["/foo"_json_pointer],
|
CHECK_THROWS_WITH_AS(j_primitive["/foo"_json_pointer], "[json.exception.out_of_range.404] unresolved reference token 'foo'", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'", json::out_of_range&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_primitive.at("/foo"_json_pointer),
|
CHECK_THROWS_WITH_AS(j_primitive.at("/foo"_json_pointer),
|
||||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'", json::out_of_range&);
|
"[json.exception.out_of_range.404] unresolved reference token 'foo'",
|
||||||
|
json::out_of_range&);
|
||||||
CHECK(!j_primitive.contains(json::json_pointer("/foo")));
|
CHECK(!j_primitive.contains(json::json_pointer("/foo")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,15 +205,14 @@ TEST_CASE("JSON pointers")
|
|||||||
CHECK(j[json::json_pointer("/m~0n")] == j["m~n"]);
|
CHECK(j[json::json_pointer("/m~0n")] == j["m~n"]);
|
||||||
|
|
||||||
// unescaped access
|
// unescaped access
|
||||||
CHECK_THROWS_WITH_AS(j.at(json::json_pointer("/a/b")),
|
CHECK_THROWS_WITH_AS(j.at(json::json_pointer("/a/b")), "[json.exception.out_of_range.403] key 'a' not found", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.403] key 'a' not found", json::out_of_range&);
|
|
||||||
|
|
||||||
// unresolved access
|
// unresolved access
|
||||||
const json j_primitive = 1;
|
const json j_primitive = 1;
|
||||||
CHECK_THROWS_WITH_AS(j_primitive["/foo"_json_pointer],
|
CHECK_THROWS_WITH_AS(j_primitive["/foo"_json_pointer], "[json.exception.out_of_range.404] unresolved reference token 'foo'", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'", json::out_of_range&);
|
|
||||||
CHECK_THROWS_WITH_AS(j_primitive.at("/foo"_json_pointer),
|
CHECK_THROWS_WITH_AS(j_primitive.at("/foo"_json_pointer),
|
||||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'", json::out_of_range&);
|
"[json.exception.out_of_range.404] unresolved reference token 'foo'",
|
||||||
|
json::out_of_range&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("user-defined string literal")
|
SECTION("user-defined string literal")
|
||||||
@@ -274,13 +273,17 @@ TEST_CASE("JSON pointers")
|
|||||||
|
|
||||||
// error with leading 0
|
// error with leading 0
|
||||||
CHECK_THROWS_WITH_AS(j["/01"_json_pointer],
|
CHECK_THROWS_WITH_AS(j["/01"_json_pointer],
|
||||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'", json::parse_error&);
|
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'",
|
||||||
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const["/01"_json_pointer],
|
CHECK_THROWS_WITH_AS(j_const["/01"_json_pointer],
|
||||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'", json::parse_error&);
|
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'",
|
||||||
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(j.at("/01"_json_pointer),
|
CHECK_THROWS_WITH_AS(j.at("/01"_json_pointer),
|
||||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'", json::parse_error&);
|
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'",
|
||||||
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const.at("/01"_json_pointer),
|
CHECK_THROWS_WITH_AS(j_const.at("/01"_json_pointer),
|
||||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'", json::parse_error&);
|
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK(!j.contains("/01"_json_pointer));
|
CHECK(!j.contains("/01"_json_pointer));
|
||||||
CHECK(!j.contains("/01"_json_pointer));
|
CHECK(!j.contains("/01"_json_pointer));
|
||||||
@@ -289,24 +292,28 @@ TEST_CASE("JSON pointers")
|
|||||||
|
|
||||||
// error with incorrect numbers
|
// error with incorrect numbers
|
||||||
CHECK_THROWS_WITH_AS(j["/one"_json_pointer] = 1,
|
CHECK_THROWS_WITH_AS(j["/one"_json_pointer] = 1,
|
||||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number", json::parse_error&);
|
"[json.exception.parse_error.109] parse error: array index 'one' is not a number",
|
||||||
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const["/one"_json_pointer] == 1,
|
CHECK_THROWS_WITH_AS(j_const["/one"_json_pointer] == 1,
|
||||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number", json::parse_error&);
|
"[json.exception.parse_error.109] parse error: array index 'one' is not a number",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j.at("/one"_json_pointer) = 1,
|
CHECK_THROWS_WITH_AS(j.at("/one"_json_pointer) = 1,
|
||||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number", json::parse_error&);
|
"[json.exception.parse_error.109] parse error: array index 'one' is not a number",
|
||||||
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const.at("/one"_json_pointer) == 1,
|
CHECK_THROWS_WITH_AS(j_const.at("/one"_json_pointer) == 1,
|
||||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number", json::parse_error&);
|
"[json.exception.parse_error.109] parse error: array index 'one' is not a number",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j["/+1"_json_pointer] = 1,
|
CHECK_THROWS_WITH_AS(j["/+1"_json_pointer] = 1,
|
||||||
"[json.exception.parse_error.109] parse error: array index '+1' is not a number", json::parse_error&);
|
"[json.exception.parse_error.109] parse error: array index '+1' is not a number",
|
||||||
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const["/+1"_json_pointer] == 1,
|
CHECK_THROWS_WITH_AS(j_const["/+1"_json_pointer] == 1,
|
||||||
"[json.exception.parse_error.109] parse error: array index '+1' is not a number", json::parse_error&);
|
"[json.exception.parse_error.109] parse error: array index '+1' is not a number",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j["/1+1"_json_pointer] = 1,
|
CHECK_THROWS_WITH_AS(j["/1+1"_json_pointer] = 1, "[json.exception.out_of_range.404] unresolved reference token '1+1'", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.404] unresolved reference token '1+1'", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(j_const["/1+1"_json_pointer] == 1, "[json.exception.out_of_range.404] unresolved reference token '1+1'", json::out_of_range&);
|
||||||
CHECK_THROWS_WITH_AS(j_const["/1+1"_json_pointer] == 1,
|
|
||||||
"[json.exception.out_of_range.404] unresolved reference token '1+1'", json::out_of_range&);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
auto too_large_index = std::to_string((std::numeric_limits<unsigned long long>::max)()) + "1";
|
auto too_large_index = std::to_string((std::numeric_limits<unsigned long long>::max)()) + "1";
|
||||||
@@ -335,9 +342,11 @@ TEST_CASE("JSON pointers")
|
|||||||
DOCTEST_MSVC_SUPPRESS_WARNING_POP
|
DOCTEST_MSVC_SUPPRESS_WARNING_POP
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j.at("/one"_json_pointer) = 1,
|
CHECK_THROWS_WITH_AS(j.at("/one"_json_pointer) = 1,
|
||||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number", json::parse_error&);
|
"[json.exception.parse_error.109] parse error: array index 'one' is not a number",
|
||||||
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_const.at("/one"_json_pointer) == 1,
|
CHECK_THROWS_WITH_AS(j_const.at("/one"_json_pointer) == 1,
|
||||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number", json::parse_error&);
|
"[json.exception.parse_error.109] parse error: array index 'one' is not a number",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK(!j.contains("/one"_json_pointer));
|
CHECK(!j.contains("/one"_json_pointer));
|
||||||
CHECK(!j.contains("/one"_json_pointer));
|
CHECK(!j.contains("/one"_json_pointer));
|
||||||
@@ -345,22 +354,20 @@ TEST_CASE("JSON pointers")
|
|||||||
CHECK(!j_const.contains("/one"_json_pointer));
|
CHECK(!j_const.contains("/one"_json_pointer));
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(json({ { "/list/0", 1 }, { "/list/1", 2 }, { "/list/three", 3 } }).unflatten(),
|
CHECK_THROWS_WITH_AS(json({ { "/list/0", 1 }, { "/list/1", 2 }, { "/list/three", 3 } }).unflatten(),
|
||||||
"[json.exception.parse_error.109] parse error: array index 'three' is not a number", json::parse_error&);
|
"[json.exception.parse_error.109] parse error: array index 'three' is not a number",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// assign to "-"
|
// assign to "-"
|
||||||
j["/-"_json_pointer] = 99;
|
j["/-"_json_pointer] = 99;
|
||||||
CHECK(j == json({ 1, 13, 3, 33, nullptr, 55, 99 }));
|
CHECK(j == json({ 1, 13, 3, 33, nullptr, 55, 99 }));
|
||||||
|
|
||||||
// error when using "-" in const object
|
// error when using "-" in const object
|
||||||
CHECK_THROWS_WITH_AS(j_const["/-"_json_pointer],
|
CHECK_THROWS_WITH_AS(j_const["/-"_json_pointer], "[json.exception.out_of_range.402] array index '-' (3) is out of range", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range", json::out_of_range&);
|
|
||||||
CHECK(!j_const.contains("/-"_json_pointer));
|
CHECK(!j_const.contains("/-"_json_pointer));
|
||||||
|
|
||||||
// error when using "-" with at
|
// error when using "-" with at
|
||||||
CHECK_THROWS_WITH_AS(j.at("/-"_json_pointer),
|
CHECK_THROWS_WITH_AS(j.at("/-"_json_pointer), "[json.exception.out_of_range.402] array index '-' (7) is out of range", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.402] array index '-' (7) is out of range", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(j_const.at("/-"_json_pointer), "[json.exception.out_of_range.402] array index '-' (3) is out of range", json::out_of_range&);
|
||||||
CHECK_THROWS_WITH_AS(j_const.at("/-"_json_pointer),
|
|
||||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range", json::out_of_range&);
|
|
||||||
CHECK(!j_const.contains("/-"_json_pointer));
|
CHECK(!j_const.contains("/-"_json_pointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,53 +381,32 @@ TEST_CASE("JSON pointers")
|
|||||||
CHECK(j["/2"_json_pointer] == j[2]);
|
CHECK(j["/2"_json_pointer] == j[2]);
|
||||||
|
|
||||||
// assign to nonexisting index
|
// assign to nonexisting index
|
||||||
CHECK_THROWS_WITH_AS(j.at("/3"_json_pointer),
|
CHECK_THROWS_WITH_AS(j.at("/3"_json_pointer), "[json.exception.out_of_range.401] array index 3 is out of range", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.401] array index 3 is out of range", json::out_of_range&);
|
|
||||||
CHECK(!j.contains("/3"_json_pointer));
|
CHECK(!j.contains("/3"_json_pointer));
|
||||||
|
|
||||||
// assign to nonexisting index (with gap)
|
// assign to nonexisting index (with gap)
|
||||||
CHECK_THROWS_WITH_AS(j.at("/5"_json_pointer),
|
CHECK_THROWS_WITH_AS(j.at("/5"_json_pointer), "[json.exception.out_of_range.401] array index 5 is out of range", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.401] array index 5 is out of range", json::out_of_range&);
|
|
||||||
CHECK(!j.contains("/5"_json_pointer));
|
CHECK(!j.contains("/5"_json_pointer));
|
||||||
|
|
||||||
// assign to "-"
|
// assign to "-"
|
||||||
CHECK_THROWS_WITH_AS(j["/-"_json_pointer],
|
CHECK_THROWS_WITH_AS(j["/-"_json_pointer], "[json.exception.out_of_range.402] array index '-' (3) is out of range", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range", json::out_of_range&);
|
CHECK_THROWS_WITH_AS(j.at("/-"_json_pointer), "[json.exception.out_of_range.402] array index '-' (3) is out of range", json::out_of_range&);
|
||||||
CHECK_THROWS_WITH_AS(j.at("/-"_json_pointer),
|
|
||||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range", json::out_of_range&);
|
|
||||||
CHECK(!j.contains("/-"_json_pointer));
|
CHECK(!j.contains("/-"_json_pointer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("flatten")
|
SECTION("flatten")
|
||||||
{
|
{
|
||||||
json j =
|
json j = { { "pi", 3.141 },
|
||||||
{
|
|
||||||
{"pi", 3.141},
|
|
||||||
{ "happy", true },
|
{ "happy", true },
|
||||||
{ "name", "Niels" },
|
{ "name", "Niels" },
|
||||||
{ "nothing", nullptr },
|
{ "nothing", nullptr },
|
||||||
{
|
{ "answer", { { "everything", 42 } } },
|
||||||
"answer", {
|
|
||||||
{"everything", 42}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ "list", { 1, 0, 2 } },
|
{ "list", { 1, 0, 2 } },
|
||||||
{
|
{ "object",
|
||||||
"object", {
|
{ { "currency", "USD" }, { "value", 42.99 }, { "", "empty string" }, { "/", "slash" }, { "~", "tilde" }, { "~1", "tilde1" } } } };
|
||||||
{"currency", "USD"},
|
|
||||||
{"value", 42.99},
|
|
||||||
{"", "empty string"},
|
|
||||||
{"/", "slash"},
|
|
||||||
{"~", "tilde"},
|
|
||||||
{"~1", "tilde1"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
json j_flatten =
|
json j_flatten = { { "/pi", 3.141 },
|
||||||
{
|
|
||||||
{"/pi", 3.141},
|
|
||||||
{ "/happy", true },
|
{ "/happy", true },
|
||||||
{ "/name", "Niels" },
|
{ "/name", "Niels" },
|
||||||
{ "/nothing", nullptr },
|
{ "/nothing", nullptr },
|
||||||
@@ -433,8 +419,7 @@ TEST_CASE("JSON pointers")
|
|||||||
{ "/object/", "empty string" },
|
{ "/object/", "empty string" },
|
||||||
{ "/object/~1", "slash" },
|
{ "/object/~1", "slash" },
|
||||||
{ "/object/~0", "tilde" },
|
{ "/object/~0", "tilde" },
|
||||||
{"/object/~01", "tilde1"}
|
{ "/object/~01", "tilde1" } };
|
||||||
};
|
|
||||||
|
|
||||||
// check if flattened result is as expected
|
// check if flattened result is as expected
|
||||||
CHECK(j.flatten() == j_flatten);
|
CHECK(j.flatten() == j_flatten);
|
||||||
@@ -443,20 +428,22 @@ TEST_CASE("JSON pointers")
|
|||||||
CHECK(j_flatten.unflatten() == j);
|
CHECK(j_flatten.unflatten() == j);
|
||||||
|
|
||||||
// error for nonobjects
|
// error for nonobjects
|
||||||
CHECK_THROWS_WITH_AS(json(1).unflatten(),
|
CHECK_THROWS_WITH_AS(json(1).unflatten(), "[json.exception.type_error.314] only objects can be unflattened", json::type_error&);
|
||||||
"[json.exception.type_error.314] only objects can be unflattened", json::type_error&);
|
|
||||||
|
|
||||||
// error for nonprimitve values
|
// error for nonprimitve values
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
CHECK_THROWS_WITH_AS(json({{"/1", {1, 2, 3}}}).unflatten(), "[json.exception.type_error.315] (/~11) values in object must be primitive", json::type_error&);
|
CHECK_THROWS_WITH_AS(json({ { "/1", { 1, 2, 3 } } }).unflatten(),
|
||||||
|
"[json.exception.type_error.315] (/~11) values in object must be primitive",
|
||||||
|
json::type_error&);
|
||||||
#else
|
#else
|
||||||
CHECK_THROWS_WITH_AS(json({{"/1", {1, 2, 3}}}).unflatten(), "[json.exception.type_error.315] values in object must be primitive", json::type_error&);
|
CHECK_THROWS_WITH_AS(json({ { "/1", { 1, 2, 3 } } }).unflatten(),
|
||||||
|
"[json.exception.type_error.315] values in object must be primitive",
|
||||||
|
json::type_error&);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// error for conflicting values
|
// error for conflicting values
|
||||||
json const j_error = { { "", 42 }, { "/foo", 17 } };
|
json const j_error = { { "", 42 }, { "/foo", 17 } };
|
||||||
CHECK_THROWS_WITH_AS(j_error.unflatten(),
|
CHECK_THROWS_WITH_AS(j_error.unflatten(), "[json.exception.type_error.313] invalid value to unflatten", json::type_error&);
|
||||||
"[json.exception.type_error.313] invalid value to unflatten", json::type_error&);
|
|
||||||
|
|
||||||
// explicit roundtrip check
|
// explicit roundtrip check
|
||||||
CHECK(j.flatten().unflatten() == j);
|
CHECK(j.flatten().unflatten() == j);
|
||||||
@@ -480,9 +467,7 @@ TEST_CASE("JSON pointers")
|
|||||||
|
|
||||||
SECTION("string representation")
|
SECTION("string representation")
|
||||||
{
|
{
|
||||||
for (const auto* ptr_str :
|
for (const auto* ptr_str : { "", "/foo", "/foo/0", "/", "/a~1b", "/c%d", "/e^f", "/g|h", "/i\\j", "/k\"l", "/ ", "/m~0n" })
|
||||||
{"", "/foo", "/foo/0", "/", "/a~1b", "/c%d", "/e^f", "/g|h", "/i\\j", "/k\"l", "/ ", "/m~0n"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
json::json_pointer const ptr(ptr_str);
|
json::json_pointer const ptr(ptr_str);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@@ -514,30 +499,15 @@ TEST_CASE("JSON pointers")
|
|||||||
|
|
||||||
SECTION("empty, push, pop and parent")
|
SECTION("empty, push, pop and parent")
|
||||||
{
|
{
|
||||||
const json j =
|
const json j = { { "", "Hello" },
|
||||||
{
|
|
||||||
{"", "Hello"},
|
|
||||||
{ "pi", 3.141 },
|
{ "pi", 3.141 },
|
||||||
{ "happy", true },
|
{ "happy", true },
|
||||||
{ "name", "Niels" },
|
{ "name", "Niels" },
|
||||||
{ "nothing", nullptr },
|
{ "nothing", nullptr },
|
||||||
{
|
{ "answer", { { "everything", 42 } } },
|
||||||
"answer", {
|
|
||||||
{"everything", 42}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ "list", { 1, 0, 2 } },
|
{ "list", { 1, 0, 2 } },
|
||||||
{
|
{ "object",
|
||||||
"object", {
|
{ { "currency", "USD" }, { "value", 42.99 }, { "", "empty string" }, { "/", "slash" }, { "~", "tilde" }, { "~1", "tilde1" } } } };
|
||||||
{"currency", "USD"},
|
|
||||||
{"value", 42.99},
|
|
||||||
{"", "empty string"},
|
|
||||||
{"/", "slash"},
|
|
||||||
{"~", "tilde"},
|
|
||||||
{"~1", "tilde1"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// empty json_pointer returns the root JSON-object
|
// empty json_pointer returns the root JSON-object
|
||||||
auto ptr = ""_json_pointer;
|
auto ptr = ""_json_pointer;
|
||||||
@@ -584,36 +554,20 @@ TEST_CASE("JSON pointers")
|
|||||||
CHECK(ptr.empty());
|
CHECK(ptr.empty());
|
||||||
CHECK(j[ptr] == j);
|
CHECK(j[ptr] == j);
|
||||||
|
|
||||||
CHECK_THROWS_WITH(ptr.pop_back(),
|
CHECK_THROWS_WITH(ptr.pop_back(), "[json.exception.out_of_range.405] JSON pointer has no parent");
|
||||||
"[json.exception.out_of_range.405] JSON pointer has no parent");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("operators")
|
SECTION("operators")
|
||||||
{
|
{
|
||||||
const json j =
|
const json j = { { "", "Hello" },
|
||||||
{
|
|
||||||
{"", "Hello"},
|
|
||||||
{ "pi", 3.141 },
|
{ "pi", 3.141 },
|
||||||
{ "happy", true },
|
{ "happy", true },
|
||||||
{ "name", "Niels" },
|
{ "name", "Niels" },
|
||||||
{ "nothing", nullptr },
|
{ "nothing", nullptr },
|
||||||
{
|
{ "answer", { { "everything", 42 } } },
|
||||||
"answer", {
|
|
||||||
{"everything", 42}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ "list", { 1, 0, 2 } },
|
{ "list", { 1, 0, 2 } },
|
||||||
{
|
{ "object",
|
||||||
"object", {
|
{ { "currency", "USD" }, { "value", 42.99 }, { "", "empty string" }, { "/", "slash" }, { "~", "tilde" }, { "~1", "tilde1" } } } };
|
||||||
{"currency", "USD"},
|
|
||||||
{"value", 42.99},
|
|
||||||
{"", "empty string"},
|
|
||||||
{"/", "slash"},
|
|
||||||
{"~", "tilde"},
|
|
||||||
{"~1", "tilde1"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// empty json_pointer returns the root JSON-object
|
// empty json_pointer returns the root JSON-object
|
||||||
auto ptr = ""_json_pointer;
|
auto ptr = ""_json_pointer;
|
||||||
@@ -687,13 +641,17 @@ TEST_CASE("JSON pointers")
|
|||||||
SECTION("exceptions")
|
SECTION("exceptions")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_WITH_AS(ptr1 == "foo",
|
CHECK_THROWS_WITH_AS(ptr1 == "foo",
|
||||||
"[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'", json::parse_error&);
|
"[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'",
|
||||||
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS("foo" == ptr1,
|
CHECK_THROWS_WITH_AS("foo" == ptr1,
|
||||||
"[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'", json::parse_error&);
|
"[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'",
|
||||||
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(ptr1 == "/~~",
|
CHECK_THROWS_WITH_AS(ptr1 == "/~~",
|
||||||
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'", json::parse_error&);
|
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'",
|
||||||
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS("/~~" == ptr1,
|
CHECK_THROWS_WITH_AS("/~~" == ptr1,
|
||||||
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'", json::parse_error&);
|
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,4 +26,3 @@ TEST_CASE("tests on very large JSONs")
|
|||||||
CHECK_NOTHROW(_ = nlohmann::json::parse(s));
|
CHECK_NOTHROW(_ = nlohmann::json::parse(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,13 +20,7 @@ TEST_CASE("version information")
|
|||||||
CHECK(j["name"] == "JSON for Modern C++");
|
CHECK(j["name"] == "JSON for Modern C++");
|
||||||
CHECK(j["copyright"] == "(C) 2013-2023 Niels Lohmann");
|
CHECK(j["copyright"] == "(C) 2013-2023 Niels Lohmann");
|
||||||
CHECK(j["url"] == "https://github.com/nlohmann/json");
|
CHECK(j["url"] == "https://github.com/nlohmann/json");
|
||||||
CHECK(j["version"] == json(
|
CHECK(j["version"] == json({ { "string", "3.11.3" }, { "major", 3 }, { "minor", 11 }, { "patch", 3 } }));
|
||||||
{
|
|
||||||
{"string", "3.11.3"},
|
|
||||||
{"major", 3},
|
|
||||||
{"minor", 11},
|
|
||||||
{"patch", 3}
|
|
||||||
}));
|
|
||||||
|
|
||||||
CHECK(j.find("platform") != j.end());
|
CHECK(j.find("platform") != j.end());
|
||||||
CHECK(j.at("compiler").find("family") != j.at("compiler").end());
|
CHECK(j.at("compiler").find("family") != j.at("compiler").end());
|
||||||
|
|||||||
@@ -239,7 +239,9 @@ TEST_CASE("modifiers")
|
|||||||
{
|
{
|
||||||
json j = 1;
|
json j = 1;
|
||||||
json const k("Hello");
|
json const k("Hello");
|
||||||
CHECK_THROWS_WITH_AS(j.push_back(json::object_t::value_type({"one", 1})), "[json.exception.type_error.308] cannot use push_back() with number", json::type_error&);
|
CHECK_THROWS_WITH_AS(j.push_back(json::object_t::value_type({ "one", 1 })),
|
||||||
|
"[json.exception.type_error.308] cannot use push_back() with number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,7 +469,9 @@ TEST_CASE("modifiers")
|
|||||||
{
|
{
|
||||||
json j = 1;
|
json j = 1;
|
||||||
json const k("Hello");
|
json const k("Hello");
|
||||||
CHECK_THROWS_WITH_AS(j += json::object_t::value_type({"one", 1}), "[json.exception.type_error.308] cannot use push_back() with number", json::type_error&);
|
CHECK_THROWS_WITH_AS(j += json::object_t::value_type({ "one", 1 }),
|
||||||
|
"[json.exception.type_error.308] cannot use push_back() with number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,9 +641,11 @@ TEST_CASE("modifiers")
|
|||||||
{
|
{
|
||||||
json j_other_array2 = { "first", "second" };
|
json j_other_array2 = { "first", "second" };
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j_array.insert(j_array.end(), j_array.begin(), j_array.end()), "[json.exception.invalid_iterator.211] passed iterators may not belong to container",
|
CHECK_THROWS_WITH_AS(j_array.insert(j_array.end(), j_array.begin(), j_array.end()),
|
||||||
|
"[json.exception.invalid_iterator.211] passed iterators may not belong to container",
|
||||||
json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()), "[json.exception.invalid_iterator.210] iterators do not fit",
|
CHECK_THROWS_WITH_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
|
||||||
|
"[json.exception.invalid_iterator.210] iterators do not fit",
|
||||||
json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -665,9 +671,15 @@ TEST_CASE("modifiers")
|
|||||||
{
|
{
|
||||||
json const j_other_array2 = { "first", "second" };
|
json const j_other_array2 = { "first", "second" };
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j_array.insert(j_object2.begin(), j_object2.end()), "[json.exception.type_error.309] cannot use insert() with array", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_array.insert(j_object2.begin(), j_object2.end()),
|
||||||
CHECK_THROWS_WITH_AS(j_object1.insert(j_object1.begin(), j_object2.end()), "[json.exception.invalid_iterator.210] iterators do not fit", json::invalid_iterator&);
|
"[json.exception.type_error.309] cannot use insert() with array",
|
||||||
CHECK_THROWS_WITH_AS(j_object1.insert(j_array.begin(), j_array.end()), "[json.exception.invalid_iterator.202] iterators first and last must point to objects", json::invalid_iterator&);
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_object1.insert(j_object1.begin(), j_object2.end()),
|
||||||
|
"[json.exception.invalid_iterator.210] iterators do not fit",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_object1.insert(j_array.begin(), j_array.end()),
|
||||||
|
"[json.exception.invalid_iterator.202] iterators first and last must point to objects",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -706,11 +718,21 @@ TEST_CASE("modifiers")
|
|||||||
// pass iterator to a different array
|
// pass iterator to a different array
|
||||||
json j_another_array = { 1, 2 };
|
json j_another_array = { 1, 2 };
|
||||||
json j_yet_another_array = { "first", "second" };
|
json j_yet_another_array = { "first", "second" };
|
||||||
CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), 10), "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), 10),
|
||||||
CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), j_value), "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.202] iterator does not fit current value",
|
||||||
CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), 10, 11), "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
|
json::invalid_iterator&);
|
||||||
CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), j_yet_another_array.end()), "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
|
CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), j_value),
|
||||||
CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&);
|
"[json.exception.invalid_iterator.202] iterator does not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), 10, 11),
|
||||||
|
"[json.exception.invalid_iterator.202] iterator does not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), j_yet_another_array.end()),
|
||||||
|
"[json.exception.invalid_iterator.202] iterator does not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_array.insert(j_another_array.end(), { 1, 2, 3, 4 }),
|
||||||
|
"[json.exception.invalid_iterator.202] iterator does not fit current value",
|
||||||
|
json::invalid_iterator&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("non-array type")
|
SECTION("non-array type")
|
||||||
@@ -719,10 +741,18 @@ TEST_CASE("modifiers")
|
|||||||
json j_nonarray = 3;
|
json j_nonarray = 3;
|
||||||
json j_yet_another_array = { "first", "second" };
|
json j_yet_another_array = { "first", "second" };
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), 10), "[json.exception.type_error.309] cannot use insert() with number", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), 10), "[json.exception.type_error.309] cannot use insert() with number", json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), j_value), "[json.exception.type_error.309] cannot use insert() with number", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), j_value),
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), 10, 11), "[json.exception.type_error.309] cannot use insert() with number", json::type_error&);
|
"[json.exception.type_error.309] cannot use insert() with number",
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(), j_yet_another_array.end()), "[json.exception.type_error.309] cannot use insert() with number", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), "[json.exception.type_error.309] cannot use insert() with number", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), 10, 11),
|
||||||
|
"[json.exception.type_error.309] cannot use insert() with number",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(), j_yet_another_array.end()),
|
||||||
|
"[json.exception.type_error.309] cannot use insert() with number",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_nonarray.insert(j_nonarray.end(), { 1, 2, 3, 4 }),
|
||||||
|
"[json.exception.type_error.309] cannot use insert() with number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -776,9 +806,15 @@ TEST_CASE("modifiers")
|
|||||||
{
|
{
|
||||||
json const j_other_array2 = { "first", "second" };
|
json const j_other_array2 = { "first", "second" };
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j_array.update(j_object2.begin(), j_object2.end()), "[json.exception.type_error.312] cannot use update() with array", json::type_error&);
|
CHECK_THROWS_WITH_AS(j_array.update(j_object2.begin(), j_object2.end()),
|
||||||
CHECK_THROWS_WITH_AS(j_object1.update(j_object1.begin(), j_object2.end()), "[json.exception.invalid_iterator.210] iterators do not fit", json::invalid_iterator&);
|
"[json.exception.type_error.312] cannot use update() with array",
|
||||||
CHECK_THROWS_WITH_AS(j_object1.update(j_array.begin(), j_array.end()), "[json.exception.type_error.312] cannot use update() with array", json::type_error&);
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_object1.update(j_object1.begin(), j_object2.end()),
|
||||||
|
"[json.exception.invalid_iterator.210] iterators do not fit",
|
||||||
|
json::invalid_iterator&);
|
||||||
|
CHECK_THROWS_WITH_AS(j_object1.update(j_array.begin(), j_array.end()),
|
||||||
|
"[json.exception.type_error.312] cannot use update() with array",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+157
-195
@@ -14,20 +14,21 @@ using nlohmann::json;
|
|||||||
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
|
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "make_test_data_available.hpp"
|
||||||
|
#include "test_utils.hpp"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "make_test_data_available.hpp"
|
#include <sstream>
|
||||||
#include "test_utils.hpp"
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class SaxCountdown
|
class SaxCountdown
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SaxCountdown(const int count) : events_left(count)
|
explicit SaxCountdown(const int count)
|
||||||
|
: events_left(count)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool null()
|
bool null()
|
||||||
@@ -90,7 +91,9 @@ class SaxCountdown
|
|||||||
return events_left-- > 0;
|
return events_left-- > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
|
bool parse_error(std::size_t /*unused*/,
|
||||||
|
const std::string& /*unused*/,
|
||||||
|
const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -168,10 +171,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_integer());
|
CHECK(j.is_number_integer());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{ static_cast<uint8_t>(i) };
|
||||||
{
|
|
||||||
static_cast<uint8_t>(i)
|
|
||||||
};
|
|
||||||
|
|
||||||
// compare result + size
|
// compare result + size
|
||||||
const auto result = json::to_msgpack(j);
|
const auto result = json::to_msgpack(j);
|
||||||
@@ -231,8 +231,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_integer());
|
CHECK(j.is_number_integer());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xcc,
|
0xcc,
|
||||||
static_cast<uint8_t>(i),
|
static_cast<uint8_t>(i),
|
||||||
};
|
};
|
||||||
@@ -267,8 +266,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_integer());
|
CHECK(j.is_number_integer());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xcd,
|
0xcd,
|
||||||
static_cast<uint8_t>((i >> 8) & 0xff),
|
static_cast<uint8_t>((i >> 8) & 0xff),
|
||||||
static_cast<uint8_t>(i & 0xff),
|
static_cast<uint8_t>(i & 0xff),
|
||||||
@@ -292,10 +290,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("65536..4294967295 (int 32)")
|
SECTION("65536..4294967295 (int 32)")
|
||||||
{
|
{
|
||||||
for (uint32_t i :
|
for (uint32_t i : { 65536u, 77777u, 1048576u, 4294967295u })
|
||||||
{
|
|
||||||
65536u, 77777u, 1048576u, 4294967295u
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(i)
|
CAPTURE(i)
|
||||||
|
|
||||||
@@ -307,8 +302,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_integer());
|
CHECK(j.is_number_integer());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xce,
|
0xce,
|
||||||
static_cast<uint8_t>((i >> 24) & 0xff),
|
static_cast<uint8_t>((i >> 24) & 0xff),
|
||||||
static_cast<uint8_t>((i >> 16) & 0xff),
|
static_cast<uint8_t>((i >> 16) & 0xff),
|
||||||
@@ -323,10 +317,8 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xce);
|
CHECK(result[0] == 0xce);
|
||||||
uint32_t const restored = (static_cast<uint32_t>(result[1]) << 030) +
|
uint32_t const restored = (static_cast<uint32_t>(result[1]) << 030) + (static_cast<uint32_t>(result[2]) << 020) +
|
||||||
(static_cast<uint32_t>(result[2]) << 020) +
|
(static_cast<uint32_t>(result[3]) << 010) + static_cast<uint32_t>(result[4]);
|
||||||
(static_cast<uint32_t>(result[3]) << 010) +
|
|
||||||
static_cast<uint32_t>(result[4]);
|
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
@@ -337,10 +329,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("4294967296..9223372036854775807 (int 64)")
|
SECTION("4294967296..9223372036854775807 (int 64)")
|
||||||
{
|
{
|
||||||
for (uint64_t i :
|
for (uint64_t i : { 4294967296LU, 9223372036854775807LU })
|
||||||
{
|
|
||||||
4294967296LU, 9223372036854775807LU
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(i)
|
CAPTURE(i)
|
||||||
|
|
||||||
@@ -352,8 +341,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_integer());
|
CHECK(j.is_number_integer());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xcf,
|
0xcf,
|
||||||
static_cast<uint8_t>((i >> 070) & 0xff),
|
static_cast<uint8_t>((i >> 070) & 0xff),
|
||||||
static_cast<uint8_t>((i >> 060) & 0xff),
|
static_cast<uint8_t>((i >> 060) & 0xff),
|
||||||
@@ -372,14 +360,10 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xcf);
|
CHECK(result[0] == 0xcf);
|
||||||
uint64_t const restored = (static_cast<uint64_t>(result[1]) << 070) +
|
uint64_t const restored = (static_cast<uint64_t>(result[1]) << 070) + (static_cast<uint64_t>(result[2]) << 060) +
|
||||||
(static_cast<uint64_t>(result[2]) << 060) +
|
(static_cast<uint64_t>(result[3]) << 050) + (static_cast<uint64_t>(result[4]) << 040) +
|
||||||
(static_cast<uint64_t>(result[3]) << 050) +
|
(static_cast<uint64_t>(result[5]) << 030) + (static_cast<uint64_t>(result[6]) << 020) +
|
||||||
(static_cast<uint64_t>(result[4]) << 040) +
|
(static_cast<uint64_t>(result[7]) << 010) + static_cast<uint64_t>(result[8]);
|
||||||
(static_cast<uint64_t>(result[5]) << 030) +
|
|
||||||
(static_cast<uint64_t>(result[6]) << 020) +
|
|
||||||
(static_cast<uint64_t>(result[7]) << 010) +
|
|
||||||
static_cast<uint64_t>(result[8]);
|
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
@@ -401,8 +385,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_integer());
|
CHECK(j.is_number_integer());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xd0,
|
0xd0,
|
||||||
static_cast<uint8_t>(i),
|
static_cast<uint8_t>(i),
|
||||||
};
|
};
|
||||||
@@ -451,8 +434,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_integer());
|
CHECK(j.is_number_integer());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xd1,
|
0xd1,
|
||||||
static_cast<uint8_t>((i >> 8) & 0xff),
|
static_cast<uint8_t>((i >> 8) & 0xff),
|
||||||
static_cast<uint8_t>(i & 0xff),
|
static_cast<uint8_t>(i & 0xff),
|
||||||
@@ -476,13 +458,8 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("-32769..-2147483648")
|
SECTION("-32769..-2147483648")
|
||||||
{
|
{
|
||||||
std::vector<int32_t> const numbers
|
std::vector<int32_t> const numbers{
|
||||||
{
|
-32769, -65536, -77777, -1048576, -2147483648LL,
|
||||||
-32769,
|
|
||||||
-65536,
|
|
||||||
-77777,
|
|
||||||
-1048576,
|
|
||||||
-2147483648LL,
|
|
||||||
};
|
};
|
||||||
for (auto i : numbers)
|
for (auto i : numbers)
|
||||||
{
|
{
|
||||||
@@ -495,8 +472,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_integer());
|
CHECK(j.is_number_integer());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xd2,
|
0xd2,
|
||||||
static_cast<uint8_t>((i >> 24) & 0xff),
|
static_cast<uint8_t>((i >> 24) & 0xff),
|
||||||
static_cast<uint8_t>((i >> 16) & 0xff),
|
static_cast<uint8_t>((i >> 16) & 0xff),
|
||||||
@@ -511,10 +487,8 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xd2);
|
CHECK(result[0] == 0xd2);
|
||||||
uint32_t const restored = (static_cast<uint32_t>(result[1]) << 030) +
|
uint32_t const restored = (static_cast<uint32_t>(result[1]) << 030) + (static_cast<uint32_t>(result[2]) << 020) +
|
||||||
(static_cast<uint32_t>(result[2]) << 020) +
|
(static_cast<uint32_t>(result[3]) << 010) + static_cast<uint32_t>(result[4]);
|
||||||
(static_cast<uint32_t>(result[3]) << 010) +
|
|
||||||
static_cast<uint32_t>(result[4]);
|
|
||||||
CHECK(static_cast<std::int32_t>(restored) == i);
|
CHECK(static_cast<std::int32_t>(restored) == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
@@ -525,8 +499,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("-9223372036854775808..-2147483649 (int 64)")
|
SECTION("-9223372036854775808..-2147483649 (int 64)")
|
||||||
{
|
{
|
||||||
std::vector<int64_t> const numbers
|
std::vector<int64_t> const numbers{
|
||||||
{
|
|
||||||
(std::numeric_limits<int64_t>::min)(),
|
(std::numeric_limits<int64_t>::min)(),
|
||||||
-2147483649LL,
|
-2147483649LL,
|
||||||
};
|
};
|
||||||
@@ -541,8 +514,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_integer());
|
CHECK(j.is_number_integer());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xd3,
|
0xd3,
|
||||||
static_cast<uint8_t>((i >> 070) & 0xff),
|
static_cast<uint8_t>((i >> 070) & 0xff),
|
||||||
static_cast<uint8_t>((i >> 060) & 0xff),
|
static_cast<uint8_t>((i >> 060) & 0xff),
|
||||||
@@ -561,14 +533,10 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xd3);
|
CHECK(result[0] == 0xd3);
|
||||||
int64_t const restored = (static_cast<int64_t>(result[1]) << 070) +
|
int64_t const restored = (static_cast<int64_t>(result[1]) << 070) + (static_cast<int64_t>(result[2]) << 060) +
|
||||||
(static_cast<int64_t>(result[2]) << 060) +
|
(static_cast<int64_t>(result[3]) << 050) + (static_cast<int64_t>(result[4]) << 040) +
|
||||||
(static_cast<int64_t>(result[3]) << 050) +
|
(static_cast<int64_t>(result[5]) << 030) + (static_cast<int64_t>(result[6]) << 020) +
|
||||||
(static_cast<int64_t>(result[4]) << 040) +
|
(static_cast<int64_t>(result[7]) << 010) + static_cast<int64_t>(result[8]);
|
||||||
(static_cast<int64_t>(result[5]) << 030) +
|
|
||||||
(static_cast<int64_t>(result[6]) << 020) +
|
|
||||||
(static_cast<int64_t>(result[7]) << 010) +
|
|
||||||
static_cast<int64_t>(result[8]);
|
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
@@ -622,8 +590,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_unsigned());
|
CHECK(j.is_number_unsigned());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xcc,
|
0xcc,
|
||||||
static_cast<uint8_t>(i),
|
static_cast<uint8_t>(i),
|
||||||
};
|
};
|
||||||
@@ -657,8 +624,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_unsigned());
|
CHECK(j.is_number_unsigned());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xcd,
|
0xcd,
|
||||||
static_cast<uint8_t>((i >> 8) & 0xff),
|
static_cast<uint8_t>((i >> 8) & 0xff),
|
||||||
static_cast<uint8_t>(i & 0xff),
|
static_cast<uint8_t>(i & 0xff),
|
||||||
@@ -682,10 +648,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("65536..4294967295 (uint 32)")
|
SECTION("65536..4294967295 (uint 32)")
|
||||||
{
|
{
|
||||||
for (const uint32_t i :
|
for (const uint32_t i : { 65536u, 77777u, 1048576u, 4294967295u })
|
||||||
{
|
|
||||||
65536u, 77777u, 1048576u, 4294967295u
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(i)
|
CAPTURE(i)
|
||||||
|
|
||||||
@@ -696,8 +659,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_unsigned());
|
CHECK(j.is_number_unsigned());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xce,
|
0xce,
|
||||||
static_cast<uint8_t>((i >> 24) & 0xff),
|
static_cast<uint8_t>((i >> 24) & 0xff),
|
||||||
static_cast<uint8_t>((i >> 16) & 0xff),
|
static_cast<uint8_t>((i >> 16) & 0xff),
|
||||||
@@ -712,10 +674,8 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xce);
|
CHECK(result[0] == 0xce);
|
||||||
uint32_t const restored = (static_cast<uint32_t>(result[1]) << 030) +
|
uint32_t const restored = (static_cast<uint32_t>(result[1]) << 030) + (static_cast<uint32_t>(result[2]) << 020) +
|
||||||
(static_cast<uint32_t>(result[2]) << 020) +
|
(static_cast<uint32_t>(result[3]) << 010) + static_cast<uint32_t>(result[4]);
|
||||||
(static_cast<uint32_t>(result[3]) << 010) +
|
|
||||||
static_cast<uint32_t>(result[4]);
|
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
@@ -726,10 +686,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("4294967296..18446744073709551615 (uint 64)")
|
SECTION("4294967296..18446744073709551615 (uint 64)")
|
||||||
{
|
{
|
||||||
for (const uint64_t i :
|
for (const uint64_t i : { 4294967296LU, 18446744073709551615LU })
|
||||||
{
|
|
||||||
4294967296LU, 18446744073709551615LU
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(i)
|
CAPTURE(i)
|
||||||
|
|
||||||
@@ -740,8 +697,7 @@ TEST_CASE("MessagePack")
|
|||||||
CHECK(j.is_number_unsigned());
|
CHECK(j.is_number_unsigned());
|
||||||
|
|
||||||
// create expected byte vector
|
// create expected byte vector
|
||||||
std::vector<uint8_t> const expected
|
std::vector<uint8_t> const expected{
|
||||||
{
|
|
||||||
0xcf,
|
0xcf,
|
||||||
static_cast<uint8_t>((i >> 070) & 0xff),
|
static_cast<uint8_t>((i >> 070) & 0xff),
|
||||||
static_cast<uint8_t>((i >> 060) & 0xff),
|
static_cast<uint8_t>((i >> 060) & 0xff),
|
||||||
@@ -760,14 +716,10 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
// check individual bytes
|
// check individual bytes
|
||||||
CHECK(result[0] == 0xcf);
|
CHECK(result[0] == 0xcf);
|
||||||
uint64_t const restored = (static_cast<uint64_t>(result[1]) << 070) +
|
uint64_t const restored = (static_cast<uint64_t>(result[1]) << 070) + (static_cast<uint64_t>(result[2]) << 060) +
|
||||||
(static_cast<uint64_t>(result[2]) << 060) +
|
(static_cast<uint64_t>(result[3]) << 050) + (static_cast<uint64_t>(result[4]) << 040) +
|
||||||
(static_cast<uint64_t>(result[3]) << 050) +
|
(static_cast<uint64_t>(result[5]) << 030) + (static_cast<uint64_t>(result[6]) << 020) +
|
||||||
(static_cast<uint64_t>(result[4]) << 040) +
|
(static_cast<uint64_t>(result[7]) << 010) + static_cast<uint64_t>(result[8]);
|
||||||
(static_cast<uint64_t>(result[5]) << 030) +
|
|
||||||
(static_cast<uint64_t>(result[6]) << 020) +
|
|
||||||
(static_cast<uint64_t>(result[7]) << 010) +
|
|
||||||
static_cast<uint64_t>(result[8]);
|
|
||||||
CHECK(restored == i);
|
CHECK(restored == i);
|
||||||
|
|
||||||
// roundtrip
|
// roundtrip
|
||||||
@@ -783,10 +735,7 @@ TEST_CASE("MessagePack")
|
|||||||
{
|
{
|
||||||
double const v = 3.1415925;
|
double const v = 3.1415925;
|
||||||
json const j = v;
|
json const j = v;
|
||||||
std::vector<uint8_t> const expected =
|
std::vector<uint8_t> const expected = { 0xcb, 0x40, 0x09, 0x21, 0xfb, 0x3f, 0xa6, 0xde, 0xfc };
|
||||||
{
|
|
||||||
0xcb, 0x40, 0x09, 0x21, 0xfb, 0x3f, 0xa6, 0xde, 0xfc
|
|
||||||
};
|
|
||||||
const auto result = json::to_msgpack(j);
|
const auto result = json::to_msgpack(j);
|
||||||
CHECK(result == expected);
|
CHECK(result == expected);
|
||||||
|
|
||||||
@@ -800,10 +749,7 @@ TEST_CASE("MessagePack")
|
|||||||
{
|
{
|
||||||
double const v = 1.0;
|
double const v = 1.0;
|
||||||
json const j = v;
|
json const j = v;
|
||||||
std::vector<uint8_t> const expected =
|
std::vector<uint8_t> const expected = { 0xca, 0x3f, 0x80, 0x00, 0x00 };
|
||||||
{
|
|
||||||
0xca, 0x3f, 0x80, 0x00, 0x00
|
|
||||||
};
|
|
||||||
const auto result = json::to_msgpack(j);
|
const auto result = json::to_msgpack(j);
|
||||||
CHECK(result == expected);
|
CHECK(result == expected);
|
||||||
|
|
||||||
@@ -817,10 +763,7 @@ TEST_CASE("MessagePack")
|
|||||||
{
|
{
|
||||||
double const v = 128.1280059814453125;
|
double const v = 128.1280059814453125;
|
||||||
json const j = v;
|
json const j = v;
|
||||||
std::vector<uint8_t> const expected =
|
std::vector<uint8_t> const expected = { 0xca, 0x43, 0x00, 0x20, 0xc5 };
|
||||||
{
|
|
||||||
0xca, 0x43, 0x00, 0x20, 0xc5
|
|
||||||
};
|
|
||||||
const auto result = json::to_msgpack(j);
|
const auto result = json::to_msgpack(j);
|
||||||
CHECK(result == expected);
|
CHECK(result == expected);
|
||||||
|
|
||||||
@@ -837,13 +780,8 @@ TEST_CASE("MessagePack")
|
|||||||
SECTION("N = 0..31")
|
SECTION("N = 0..31")
|
||||||
{
|
{
|
||||||
// explicitly enumerate the first byte for all 32 strings
|
// explicitly enumerate the first byte for all 32 strings
|
||||||
const std::vector<uint8_t> first_bytes =
|
const std::vector<uint8_t> first_bytes = { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||||
{
|
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf };
|
||||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
|
|
||||||
0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1,
|
|
||||||
0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
|
|
||||||
0xbb, 0xbc, 0xbd, 0xbe, 0xbf
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t N = 0; N < first_bytes.size(); ++N)
|
for (size_t N = 0; N < first_bytes.size(); ++N)
|
||||||
{
|
{
|
||||||
@@ -914,10 +852,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("N = 256..65535")
|
SECTION("N = 256..65535")
|
||||||
{
|
{
|
||||||
for (size_t N :
|
for (size_t N : { 256u, 999u, 1025u, 3333u, 2048u, 65535u })
|
||||||
{
|
|
||||||
256u, 999u, 1025u, 3333u, 2048u, 65535u
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(N)
|
CAPTURE(N)
|
||||||
|
|
||||||
@@ -947,10 +882,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("N = 65536..4294967295")
|
SECTION("N = 65536..4294967295")
|
||||||
{
|
{
|
||||||
for (size_t N :
|
for (size_t N : { 65536u, 77777u, 1048576u })
|
||||||
{
|
|
||||||
65536u, 77777u, 1048576u
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(N)
|
CAPTURE(N)
|
||||||
|
|
||||||
@@ -1100,10 +1032,7 @@ TEST_CASE("MessagePack")
|
|||||||
SECTION("{\"a\": {\"b\": {\"c\": {}}}}")
|
SECTION("{\"a\": {\"b\": {\"c\": {}}}}")
|
||||||
{
|
{
|
||||||
json const j = json::parse(R"({"a": {"b": {"c": {}}}})");
|
json const j = json::parse(R"({"a": {"b": {"c": {}}}})");
|
||||||
std::vector<uint8_t> const expected =
|
std::vector<uint8_t> const expected = { 0x81, 0xa1, 0x61, 0x81, 0xa1, 0x62, 0x81, 0xa1, 0x63, 0x80 };
|
||||||
{
|
|
||||||
0x81, 0xa1, 0x61, 0x81, 0xa1, 0x62, 0x81, 0xa1, 0x63, 0x80
|
|
||||||
};
|
|
||||||
const auto result = json::to_msgpack(j);
|
const auto result = json::to_msgpack(j);
|
||||||
CHECK(result == expected);
|
CHECK(result == expected);
|
||||||
|
|
||||||
@@ -1244,10 +1173,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("N = 256..65535")
|
SECTION("N = 256..65535")
|
||||||
{
|
{
|
||||||
for (std::size_t N :
|
for (std::size_t N : { 256u, 999u, 1025u, 3333u, 2048u, 65535u })
|
||||||
{
|
|
||||||
256u, 999u, 1025u, 3333u, 2048u, 65535u
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(N)
|
CAPTURE(N)
|
||||||
|
|
||||||
@@ -1280,10 +1206,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("N = 65536..4294967295")
|
SECTION("N = 65536..4294967295")
|
||||||
{
|
{
|
||||||
for (std::size_t N :
|
for (std::size_t N : { 65536u, 77777u, 1048576u })
|
||||||
{
|
|
||||||
65536u, 77777u, 1048576u
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(N)
|
CAPTURE(N)
|
||||||
|
|
||||||
@@ -1356,10 +1279,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("N = 256..65535")
|
SECTION("N = 256..65535")
|
||||||
{
|
{
|
||||||
for (std::size_t N :
|
for (std::size_t N : { 256u, 999u, 1025u, 3333u, 2048u, 65535u })
|
||||||
{
|
|
||||||
256u, 999u, 1025u, 3333u, 2048u, 65535u
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(N)
|
CAPTURE(N)
|
||||||
|
|
||||||
@@ -1389,10 +1309,7 @@ TEST_CASE("MessagePack")
|
|||||||
|
|
||||||
SECTION("N = 65536..4294967295")
|
SECTION("N = 65536..4294967295")
|
||||||
{
|
{
|
||||||
for (std::size_t N :
|
for (std::size_t N : { 65536u, 77777u, 1048576u })
|
||||||
{
|
|
||||||
65536u, 77777u, 1048576u
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(N)
|
CAPTURE(N)
|
||||||
|
|
||||||
@@ -1436,7 +1353,10 @@ TEST_CASE("MessagePack")
|
|||||||
SECTION("empty byte vector")
|
SECTION("empty byte vector")
|
||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>()), "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>()),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
CHECK(json::from_msgpack(std::vector<uint8_t>(), true, false).is_discarded());
|
CHECK(json::from_msgpack(std::vector<uint8_t>(), true, false).is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1444,46 +1364,86 @@ TEST_CASE("MessagePack")
|
|||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0x87})),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input", json::parse_error&);
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0x87 })),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcc})),
|
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input",
|
||||||
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcd})),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xcc })),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})),
|
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xce})),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xcd })),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})),
|
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00})),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xcd, 0x00 })),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00})),
|
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf})),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xce })),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00})),
|
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00})),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xce, 0x00 })),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00})),
|
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00})),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xce, 0x00, 0x00 })),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00})),
|
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
"[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xce, 0x00, 0x00, 0x00 })),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
|
"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
"[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xa5, 0x68, 0x65})),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack string: unexpected end of input", json::parse_error&);
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xcf })),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0x92, 0x01})),
|
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack value: unexpected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0x81, 0xa1, 0x61})),
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack value: unexpected end of input", json::parse_error&);
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xcf, 0x00 })),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xc4, 0x02})),
|
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack binary: unexpected end of input", json::parse_error&);
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xcf, 0x00, 0x00 })),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xcf, 0x00, 0x00, 0x00 })),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xcf, 0x00, 0x00, 0x00, 0x00 })),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00 })),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xa5, 0x68, 0x65 })),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack string: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0x92, 0x01 })),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack value: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0x81, 0xa1, 0x61 })),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack value: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0xc4, 0x02 })),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack binary: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK(json::from_msgpack(std::vector<uint8_t>({ 0x87 }), true, false).is_discarded());
|
CHECK(json::from_msgpack(std::vector<uint8_t>({ 0x87 }), true, false).is_discarded());
|
||||||
CHECK(json::from_msgpack(std::vector<uint8_t>({ 0xcc }), true, false).is_discarded());
|
CHECK(json::from_msgpack(std::vector<uint8_t>({ 0xcc }), true, false).is_discarded());
|
||||||
@@ -1513,16 +1473,15 @@ TEST_CASE("MessagePack")
|
|||||||
SECTION("concrete examples")
|
SECTION("concrete examples")
|
||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xc1})), "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC1", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({ 0xc1 })),
|
||||||
|
"[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC1",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("all unsupported bytes")
|
SECTION("all unsupported bytes")
|
||||||
{
|
{
|
||||||
for (auto byte :
|
for (auto byte : { // never used
|
||||||
{
|
0xc1 })
|
||||||
// never used
|
|
||||||
0xc1
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({ static_cast<uint8_t>(byte) })), json::parse_error&);
|
CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({ static_cast<uint8_t>(byte) })), json::parse_error&);
|
||||||
@@ -1534,7 +1493,10 @@ TEST_CASE("MessagePack")
|
|||||||
SECTION("invalid string in map")
|
SECTION("invalid string in map")
|
||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01})), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack string: expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0xFF", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(std::vector<uint8_t>({ 0x81, 0xff, 0x01 })),
|
||||||
|
"[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack string: expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0xFF",
|
||||||
|
json::parse_error&);
|
||||||
CHECK(json::from_msgpack(std::vector<uint8_t>({ 0x81, 0xff, 0x01 }), true, false).is_discarded());
|
CHECK(json::from_msgpack(std::vector<uint8_t>({ 0x81, 0xff, 0x01 }), true, false).is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1550,7 +1512,10 @@ TEST_CASE("MessagePack")
|
|||||||
SECTION("strict mode")
|
SECTION("strict mode")
|
||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack value: expected end of input; last byte: 0xC0", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_msgpack(vec),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack value: expected end of input; last byte: 0xC0",
|
||||||
|
json::parse_error&);
|
||||||
CHECK(json::from_msgpack(vec, true, false).is_discarded());
|
CHECK(json::from_msgpack(vec, true, false).is_discarded());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1646,9 +1611,7 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip())
|
|||||||
exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_simple.json");
|
exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_simple.json");
|
||||||
exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_string_unicode.json");
|
exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_string_unicode.json");
|
||||||
|
|
||||||
for (std::string filename :
|
for (std::string filename : { TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json",
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json",
|
|
||||||
TEST_DATA_DIRECTORY "/json.org/1.json",
|
TEST_DATA_DIRECTORY "/json.org/1.json",
|
||||||
TEST_DATA_DIRECTORY "/json.org/2.json",
|
TEST_DATA_DIRECTORY "/json.org/2.json",
|
||||||
TEST_DATA_DIRECTORY "/json.org/3.json",
|
TEST_DATA_DIRECTORY "/json.org/3.json",
|
||||||
@@ -1792,8 +1755,7 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip())
|
|||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_string_empty.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_string_empty.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_trailing_newline.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_trailing_newline.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_true_in_array.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_true_in_array.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_whitespace_array.json"
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_whitespace_array.json" })
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
struct Foo
|
struct Foo
|
||||||
{
|
{
|
||||||
@@ -82,5 +82,3 @@ TEST_CASE("check_for_mem_leak_on_adl_to_json-2")
|
|||||||
// just ignore the exception in this POC
|
// just ignore the exception in this POC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,14 @@ using nlohmann::json;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
enum test {};
|
enum test
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
struct pod {};
|
struct pod
|
||||||
struct pod_bis {};
|
{};
|
||||||
|
struct pod_bis
|
||||||
|
{};
|
||||||
|
|
||||||
void to_json(json& /*unused*/, pod /*unused*/) noexcept;
|
void to_json(json& /*unused*/, pod /*unused*/) noexcept;
|
||||||
void to_json(json& /*unused*/, pod_bis /*unused*/);
|
void to_json(json& /*unused*/, pod_bis /*unused*/);
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ using nlohmann::json;
|
|||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <forward_list>
|
#include <forward_list>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <sstream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
// local variable is initialized but not referenced
|
// local variable is initialized but not referenced
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
|
DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
|
||||||
@@ -61,25 +61,13 @@ TEST_CASE("README" * doctest::skip())
|
|||||||
j["object"] = { { "currency", "USD" }, { "value", 42.99 } };
|
j["object"] = { { "currency", "USD" }, { "value", 42.99 } };
|
||||||
|
|
||||||
// instead, you could also write (which looks very similar to the JSON above)
|
// instead, you could also write (which looks very similar to the JSON above)
|
||||||
json const j2 =
|
json const j2 = { { "pi", 3.141 },
|
||||||
{
|
|
||||||
{"pi", 3.141},
|
|
||||||
{ "happy", true },
|
{ "happy", true },
|
||||||
{ "name", "Niels" },
|
{ "name", "Niels" },
|
||||||
{ "nothing", nullptr },
|
{ "nothing", nullptr },
|
||||||
{
|
{ "answer", { { "everything", 42 } } },
|
||||||
"answer", {
|
|
||||||
{"everything", 42}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ "list", { 1, 0, 2 } },
|
{ "list", { 1, 0, 2 } },
|
||||||
{
|
{ "object", { { "currency", "USD" }, { "value", 42.99 } } } };
|
||||||
"object", {
|
|
||||||
{"currency", "USD"},
|
|
||||||
{"value", 42.99}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,19 +14,11 @@ using nlohmann::json;
|
|||||||
TEST_CASE("reference access")
|
TEST_CASE("reference access")
|
||||||
{
|
{
|
||||||
// create a JSON value with different types
|
// create a JSON value with different types
|
||||||
const json json_types =
|
const json json_types = { { "boolean", true },
|
||||||
{
|
{ "number", { { "integer", 42 }, { "floating-point", 17.23 } } },
|
||||||
{"boolean", true},
|
|
||||||
{
|
|
||||||
"number", {
|
|
||||||
{"integer", 42},
|
|
||||||
{"floating-point", 17.23}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ "string", "Hello, world!" },
|
{ "string", "Hello, world!" },
|
||||||
{ "array", { 1, 2, 3, 4, 5 } },
|
{ "array", { 1, 2, 3, 4, 5 } },
|
||||||
{"null", nullptr}
|
{ "null", nullptr } };
|
||||||
};
|
|
||||||
|
|
||||||
SECTION("reference access to object_t")
|
SECTION("reference access to object_t")
|
||||||
{
|
{
|
||||||
@@ -45,17 +37,23 @@ TEST_CASE("reference access")
|
|||||||
// check if mismatching references throw correctly
|
// check if mismatching references throw correctly
|
||||||
CHECK_NOTHROW(value.get_ref<json::object_t&>());
|
CHECK_NOTHROW(value.get_ref<json::object_t&>());
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("const reference access to const object_t")
|
SECTION("const reference access to const object_t")
|
||||||
@@ -88,18 +86,24 @@ TEST_CASE("reference access")
|
|||||||
|
|
||||||
// check if mismatching references throw correctly
|
// check if mismatching references throw correctly
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array",
|
||||||
|
json::type_error&);
|
||||||
CHECK_NOTHROW(value.get_ref<json::array_t&>());
|
CHECK_NOTHROW(value.get_ref<json::array_t&>());
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("reference access to string_t")
|
SECTION("reference access to string_t")
|
||||||
@@ -118,18 +122,24 @@ TEST_CASE("reference access")
|
|||||||
|
|
||||||
// check if mismatching references throw correctly
|
// check if mismatching references throw correctly
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string",
|
||||||
|
json::type_error&);
|
||||||
CHECK_NOTHROW(value.get_ref<json::string_t&>());
|
CHECK_NOTHROW(value.get_ref<json::string_t&>());
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("reference access to boolean_t")
|
SECTION("reference access to boolean_t")
|
||||||
@@ -148,18 +158,24 @@ TEST_CASE("reference access")
|
|||||||
|
|
||||||
// check if mismatching references throw correctly
|
// check if mismatching references throw correctly
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean",
|
||||||
|
json::type_error&);
|
||||||
CHECK_NOTHROW(value.get_ref<json::boolean_t&>());
|
CHECK_NOTHROW(value.get_ref<json::boolean_t&>());
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("reference access to number_integer_t")
|
SECTION("reference access to number_integer_t")
|
||||||
@@ -178,18 +194,24 @@ TEST_CASE("reference access")
|
|||||||
|
|
||||||
// check if mismatching references throw correctly
|
// check if mismatching references throw correctly
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_NOTHROW(value.get_ref<json::number_integer_t&>());
|
CHECK_NOTHROW(value.get_ref<json::number_integer_t&>());
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("reference access to number_unsigned_t")
|
SECTION("reference access to number_unsigned_t")
|
||||||
@@ -208,17 +230,23 @@ TEST_CASE("reference access")
|
|||||||
|
|
||||||
// check if mismatching references throw correctly
|
// check if mismatching references throw correctly
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
||||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
//CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
//CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
||||||
// "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
// "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
||||||
CHECK_NOTHROW(value.get_ref<json::number_unsigned_t&>());
|
CHECK_NOTHROW(value.get_ref<json::number_unsigned_t&>());
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(),
|
||||||
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("reference access to number_float_t")
|
SECTION("reference access to number_float_t")
|
||||||
@@ -236,12 +264,24 @@ TEST_CASE("reference access")
|
|||||||
CHECK(p2 == value.get<test_type>());
|
CHECK(p2 == value.get<test_type>());
|
||||||
|
|
||||||
// check if mismatching references throw correctly
|
// check if mismatching references throw correctly
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
CHECK_THROWS_WITH_AS(value.get_ref<json::object_t&>(),
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
CHECK_THROWS_WITH_AS(value.get_ref<json::array_t&>(),
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(value.get_ref<json::string_t&>(),
|
||||||
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
||||||
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
||||||
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(value.get_ref<json::number_unsigned_t&>(),
|
||||||
|
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number",
|
||||||
|
json::type_error&);
|
||||||
CHECK_NOTHROW(value.get_ref<json::number_float_t&>());
|
CHECK_NOTHROW(value.get_ref<json::number_float_t&>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+184
-168
@@ -18,12 +18,12 @@ using nlohmann::json;
|
|||||||
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
|
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <list>
|
|
||||||
#include <limits>
|
|
||||||
#include <cstdio>
|
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
|
#include <cstdio>
|
||||||
|
#include <fstream>
|
||||||
|
#include <limits>
|
||||||
|
#include <list>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
#include <variant>
|
#include <variant>
|
||||||
@@ -84,8 +84,8 @@ struct foo_serializer < T, typename std::enable_if < !std::is_same<foo, T>::valu
|
|||||||
};
|
};
|
||||||
} // namespace ns
|
} // namespace ns
|
||||||
|
|
||||||
using foo_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t,
|
using foo_json = nlohmann::
|
||||||
std::uint64_t, double, std::allocator, ns::foo_serializer, std::vector<std::uint8_t>>;
|
basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, ns::foo_serializer, std::vector<std::uint8_t>>;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
// for #805
|
// for #805
|
||||||
@@ -171,7 +171,11 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
SECTION("pull request #71 - handle enum type")
|
SECTION("pull request #71 - handle enum type")
|
||||||
{
|
{
|
||||||
enum { t = 0, u = 102};
|
enum
|
||||||
|
{
|
||||||
|
t = 0,
|
||||||
|
u = 102
|
||||||
|
};
|
||||||
json j = json::array();
|
json j = json::array();
|
||||||
j.push_back(t);
|
j.push_back(t);
|
||||||
|
|
||||||
@@ -186,10 +190,7 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
static_assert(std::is_same<decltype(anon_enum_value), decltype(u)>::value, "types must be the same");
|
static_assert(std::is_same<decltype(anon_enum_value), decltype(u)>::value, "types must be the same");
|
||||||
|
|
||||||
j.push_back(json::object(
|
j.push_back(json::object({ { "game_type", t } }));
|
||||||
{
|
|
||||||
{"game_type", t}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #76 - dump() / parse() not idempotent")
|
SECTION("issue #76 - dump() / parse() not idempotent")
|
||||||
@@ -249,8 +250,7 @@ TEST_CASE("regression tests 1")
|
|||||||
SECTION("issue #89 - nonstandard integer type")
|
SECTION("issue #89 - nonstandard integer type")
|
||||||
{
|
{
|
||||||
// create JSON class with nonstandard integer number type
|
// create JSON class with nonstandard integer number type
|
||||||
using custom_json =
|
using custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float>;
|
||||||
nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float>;
|
|
||||||
custom_json j;
|
custom_json j;
|
||||||
j["int_1"] = 1;
|
j["int_1"] = 1;
|
||||||
CHECK(j["int_1"] == 1);
|
CHECK(j["int_1"] == 1);
|
||||||
@@ -298,8 +298,7 @@ TEST_CASE("regression tests 1")
|
|||||||
json::reverse_iterator rit = a.rbegin();
|
json::reverse_iterator rit = a.rbegin();
|
||||||
++rit;
|
++rit;
|
||||||
json b = { 0, 0, 0 };
|
json b = { 0, 0, 0 };
|
||||||
std::transform(rit, a.rend(), b.rbegin(), [](json el)
|
std::transform(rit, a.rend(), b.rbegin(), [](json el) {
|
||||||
{
|
|
||||||
return el;
|
return el;
|
||||||
});
|
});
|
||||||
CHECK(b == json({ 0, 1, 2 }));
|
CHECK(b == json({ 0, 1, 2 }));
|
||||||
@@ -307,8 +306,7 @@ TEST_CASE("regression tests 1")
|
|||||||
{
|
{
|
||||||
json a = { 1, 2, 3 };
|
json a = { 1, 2, 3 };
|
||||||
json b = { 0, 0, 0 };
|
json b = { 0, 0, 0 };
|
||||||
std::transform(++a.rbegin(), a.rend(), b.rbegin(), [](json el)
|
std::transform(++a.rbegin(), a.rend(), b.rbegin(), [](json el) {
|
||||||
{
|
|
||||||
return el;
|
return el;
|
||||||
});
|
});
|
||||||
CHECK(b == json({ 0, 1, 2 }));
|
CHECK(b == json({ 0, 1, 2 }));
|
||||||
@@ -317,12 +315,7 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
SECTION("issue #100 - failed to iterator json object with reverse_iterator")
|
SECTION("issue #100 - failed to iterator json object with reverse_iterator")
|
||||||
{
|
{
|
||||||
json config =
|
json config = { { "111", 111 }, { "112", 112 }, { "113", 113 } };
|
||||||
{
|
|
||||||
{ "111", 111 },
|
|
||||||
{ "112", 112 },
|
|
||||||
{ "113", 113 }
|
|
||||||
};
|
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
@@ -342,7 +335,9 @@ TEST_CASE("regression tests 1")
|
|||||||
SECTION("issue #101 - binary string causes numbers to be dumped as hex")
|
SECTION("issue #101 - binary string causes numbers to be dumped as hex")
|
||||||
{
|
{
|
||||||
int64_t const number = 10;
|
int64_t const number = 10;
|
||||||
std::string const bytes{"\x00" "asdf\n", 6};
|
std::string const bytes{ "\x00"
|
||||||
|
"asdf\n",
|
||||||
|
6 };
|
||||||
json j;
|
json j;
|
||||||
j["int64"] = number;
|
j["int64"] = number;
|
||||||
j["binary string"] = bytes;
|
j["binary string"] = bytes;
|
||||||
@@ -466,18 +461,15 @@ TEST_CASE("regression tests 1")
|
|||||||
// create JSON class with nonstandard float number type
|
// create JSON class with nonstandard float number type
|
||||||
|
|
||||||
// float
|
// float
|
||||||
nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float> const j_float =
|
nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float> const j_float = 1.23e25f;
|
||||||
1.23e25f;
|
|
||||||
CHECK(j_float.get<float>() == 1.23e25f);
|
CHECK(j_float.get<float>() == 1.23e25f);
|
||||||
|
|
||||||
// double
|
// double
|
||||||
nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, double> const j_double =
|
nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, double> const j_double = 1.23e35;
|
||||||
1.23e35;
|
|
||||||
CHECK(j_double.get<double>() == 1.23e35);
|
CHECK(j_double.get<double>() == 1.23e35);
|
||||||
|
|
||||||
// long double
|
// long double
|
||||||
nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, long double>
|
nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, long double> const j_long_double = 1.23e45L;
|
||||||
const j_long_double = 1.23e45L;
|
|
||||||
CHECK(j_long_double.get<long double>() == 1.23e45L);
|
CHECK(j_long_double.get<long double>() == 1.23e45L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,8 +587,7 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
SECTION("issue #283 - value() does not work with _json_pointer types")
|
SECTION("issue #283 - value() does not work with _json_pointer types")
|
||||||
{
|
{
|
||||||
json j =
|
json j = {
|
||||||
{
|
|
||||||
{ "object", { { "key1", 1 }, { "key2", 2 } } },
|
{ "object", { { "key1", 1 }, { "key2", 2 } } },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -617,11 +608,7 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
SECTION("issue #306 - Parsing fails without space at end of file")
|
SECTION("issue #306 - Parsing fails without space at end of file")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { TEST_DATA_DIRECTORY "/regression/broken_file.json", TEST_DATA_DIRECTORY "/regression/working_file.json" })
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/regression/broken_file.json",
|
|
||||||
TEST_DATA_DIRECTORY "/regression/working_file.json"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
json j;
|
json j;
|
||||||
@@ -632,13 +619,10 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
SECTION("issue #310 - make json_benchmarks no longer working in 2.0.4")
|
SECTION("issue #310 - make json_benchmarks no longer working in 2.0.4")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { TEST_DATA_DIRECTORY "/regression/floats.json",
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/regression/floats.json",
|
|
||||||
TEST_DATA_DIRECTORY "/regression/signed_ints.json",
|
TEST_DATA_DIRECTORY "/regression/signed_ints.json",
|
||||||
TEST_DATA_DIRECTORY "/regression/unsigned_ints.json",
|
TEST_DATA_DIRECTORY "/regression/unsigned_ints.json",
|
||||||
TEST_DATA_DIRECTORY "/regression/small_signed_ints.json"
|
TEST_DATA_DIRECTORY "/regression/small_signed_ints.json" })
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
json j;
|
json j;
|
||||||
@@ -662,8 +646,7 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
SECTION("issue #360 - Loss of precision when serializing <double>")
|
SECTION("issue #360 - Loss of precision when serializing <double>")
|
||||||
{
|
{
|
||||||
auto check_roundtrip = [](double number)
|
auto check_roundtrip = [](double number) {
|
||||||
{
|
|
||||||
CAPTURE(number)
|
CAPTURE(number)
|
||||||
|
|
||||||
json j = number;
|
json j = number;
|
||||||
@@ -722,7 +705,10 @@ TEST_CASE("regression tests 1")
|
|||||||
{
|
{
|
||||||
std::ifstream f("file_not_found.json");
|
std::ifstream f("file_not_found.json");
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse(f), "[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse(f),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #367 - calling stream at EOF")
|
SECTION("issue #367 - calling stream at EOF")
|
||||||
@@ -736,7 +722,10 @@ TEST_CASE("regression tests 1")
|
|||||||
// ss is not at EOF; this yielded an error before the fix
|
// ss is not at EOF; this yielded an error before the fix
|
||||||
// (threw basic_string::append). No, it should just throw
|
// (threw basic_string::append). No, it should just throw
|
||||||
// a parse error because of the EOF.
|
// a parse error because of the EOF.
|
||||||
CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
ss >> j,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #367 - behavior of operator>> should more closely resemble that of built-in overloads")
|
SECTION("issue #367 - behavior of operator>> should more closely resemble that of built-in overloads")
|
||||||
@@ -745,7 +734,10 @@ TEST_CASE("regression tests 1")
|
|||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
json j;
|
json j;
|
||||||
CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
ss >> j,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("(whitespace)")
|
SECTION("(whitespace)")
|
||||||
@@ -753,8 +745,10 @@ TEST_CASE("regression tests 1")
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << " ";
|
ss << " ";
|
||||||
json j;
|
json j;
|
||||||
CHECK_THROWS_WITH_AS(ss >> j,
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
|
ss >> j,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("one value")
|
SECTION("one value")
|
||||||
@@ -765,7 +759,10 @@ TEST_CASE("regression tests 1")
|
|||||||
CHECK_NOTHROW(ss >> j);
|
CHECK_NOTHROW(ss >> j);
|
||||||
CHECK(j == 111);
|
CHECK(j == 111);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
ss >> j,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("one value + whitespace")
|
SECTION("one value + whitespace")
|
||||||
@@ -776,8 +773,10 @@ TEST_CASE("regression tests 1")
|
|||||||
CHECK_NOTHROW(ss >> j);
|
CHECK_NOTHROW(ss >> j);
|
||||||
CHECK(j == 222);
|
CHECK(j == 222);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(ss >> j,
|
CHECK_THROWS_WITH_AS(
|
||||||
"[json.exception.parse_error.101] parse error at line 2, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
|
ss >> j,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 2, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("whitespace + one value")
|
SECTION("whitespace + one value")
|
||||||
@@ -788,7 +787,10 @@ TEST_CASE("regression tests 1")
|
|||||||
CHECK_NOTHROW(ss >> j);
|
CHECK_NOTHROW(ss >> j);
|
||||||
CHECK(j == 333);
|
CHECK(j == 333);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
ss >> j,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("three values")
|
SECTION("three values")
|
||||||
@@ -803,7 +805,10 @@ TEST_CASE("regression tests 1")
|
|||||||
CHECK_NOTHROW(ss >> j);
|
CHECK_NOTHROW(ss >> j);
|
||||||
CHECK(j == 333);
|
CHECK(j == 333);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
ss >> j,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("literals without whitespace")
|
SECTION("literals without whitespace")
|
||||||
@@ -820,7 +825,10 @@ TEST_CASE("regression tests 1")
|
|||||||
CHECK_NOTHROW(ss >> j);
|
CHECK_NOTHROW(ss >> j);
|
||||||
CHECK(j == "");
|
CHECK(j == "");
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
ss >> j,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("example from #529")
|
SECTION("example from #529")
|
||||||
@@ -833,7 +841,10 @@ TEST_CASE("regression tests 1")
|
|||||||
CHECK_NOTHROW(ss >> j);
|
CHECK_NOTHROW(ss >> j);
|
||||||
CHECK(j == json({ { "three", 3 } }));
|
CHECK(j == json({ { "three", 3 } }));
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
ss >> j,
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("second example from #529")
|
SECTION("second example from #529")
|
||||||
@@ -902,7 +913,9 @@ TEST_CASE("regression tests 1")
|
|||||||
// original test case
|
// original test case
|
||||||
std::vector<uint8_t> const vec{ 0x65, 0xf5, 0x0a, 0x48, 0x21 };
|
std::vector<uint8_t> const vec{ 0x65, 0xf5, 0x0a, 0x48, 0x21 };
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec), "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR string: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)")
|
SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)")
|
||||||
@@ -911,23 +924,33 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
// original test case: incomplete float64
|
// original test case: incomplete float64
|
||||||
std::vector<uint8_t> const vec1{ 0xcb, 0x8f, 0x0a };
|
std::vector<uint8_t> const vec1{ 0xcb, 0x8f, 0x0a };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec1), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec1),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// related test case: incomplete float32
|
// related test case: incomplete float32
|
||||||
std::vector<uint8_t> const vec2{ 0xca, 0x8f, 0x0a };
|
std::vector<uint8_t> const vec2{ 0xca, 0x8f, 0x0a };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec2), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec2),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// related test case: incomplete Half-Precision Float (CBOR)
|
// related test case: incomplete Half-Precision Float (CBOR)
|
||||||
std::vector<uint8_t> const vec3{ 0xf9, 0x8f };
|
std::vector<uint8_t> const vec3{ 0xf9, 0x8f };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// related test case: incomplete Single-Precision Float (CBOR)
|
// related test case: incomplete Single-Precision Float (CBOR)
|
||||||
std::vector<uint8_t> const vec4{ 0xfa, 0x8f, 0x0a };
|
std::vector<uint8_t> const vec4{ 0xfa, 0x8f, 0x0a };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec4), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec4),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// related test case: incomplete Double-Precision Float (CBOR)
|
// related test case: incomplete Double-Precision Float (CBOR)
|
||||||
std::vector<uint8_t> const vec5{ 0xfb, 0x8f, 0x0a };
|
std::vector<uint8_t> const vec5{ 0xfb, 0x8f, 0x0a };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec5), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec5),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)")
|
SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)")
|
||||||
@@ -936,30 +959,31 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
// original test case
|
// original test case
|
||||||
std::vector<uint8_t> const vec1{ 0x87 };
|
std::vector<uint8_t> const vec1{ 0x87 };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec1), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec1),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// more test cases for MessagePack
|
// more test cases for MessagePack
|
||||||
for (auto b :
|
for (auto b : { 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
|
||||||
{
|
0x8f, // fixmap
|
||||||
0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, // fixmap
|
0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e,
|
||||||
0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, // fixarray
|
0x9f, // fixarray
|
||||||
0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, // fixstr
|
0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
|
||||||
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf
|
0xaf, // fixstr
|
||||||
})
|
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf })
|
||||||
{
|
{
|
||||||
std::vector<uint8_t> const vec(1, static_cast<uint8_t>(b));
|
std::vector<uint8_t> const vec(1, static_cast<uint8_t>(b));
|
||||||
CHECK_THROWS_AS(_ = json::from_msgpack(vec), json::parse_error&);
|
CHECK_THROWS_AS(_ = json::from_msgpack(vec), json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
// more test cases for CBOR
|
// more test cases for CBOR
|
||||||
for (auto b :
|
for (auto b : {
|
||||||
{
|
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
|
||||||
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
0x77, // UTF-8 string
|
||||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // UTF-8 string
|
0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
|
||||||
0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
0x97, // array
|
||||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, // array
|
0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
|
||||||
0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
0xb7 // map
|
||||||
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7 // map
|
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
std::vector<uint8_t> const vec(1, static_cast<uint8_t>(b));
|
std::vector<uint8_t> const vec(1, static_cast<uint8_t>(b));
|
||||||
@@ -968,8 +992,12 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
// special case: empty input
|
// special case: empty input
|
||||||
std::vector<uint8_t> const vec2;
|
std::vector<uint8_t> const vec2;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2),
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec2), "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input", json::parse_error&);
|
"[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec2),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)")
|
SECTION("issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)")
|
||||||
@@ -978,55 +1006,57 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
// original test case: empty UTF-8 string (indefinite length)
|
// original test case: empty UTF-8 string (indefinite length)
|
||||||
std::vector<uint8_t> const vec1{ 0x7f };
|
std::vector<uint8_t> const vec1{ 0x7f };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec1), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec1),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// related test case: empty array (indefinite length)
|
// related test case: empty array (indefinite length)
|
||||||
std::vector<uint8_t> const vec2{ 0x9f };
|
std::vector<uint8_t> const vec2{ 0x9f };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// related test case: empty map (indefinite length)
|
// related test case: empty map (indefinite length)
|
||||||
std::vector<uint8_t> const vec3{ 0xbf };
|
std::vector<uint8_t> const vec3{ 0xbf };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)")
|
SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)")
|
||||||
{
|
{
|
||||||
// original test case
|
// original test case
|
||||||
std::vector<uint8_t> const vec
|
std::vector<uint8_t> const vec{ 0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00, 0x60, 0xab, 0x98, 0x98,
|
||||||
{
|
0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
0x60, 0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xa0, 0x9f, 0x9f, 0x97, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60 };
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xa0, 0x9f,
|
|
||||||
0x9f, 0x97, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
|
||||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60
|
|
||||||
};
|
|
||||||
|
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x98", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_cbor(vec),
|
||||||
|
"[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x98",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// related test case: nonempty UTF-8 string (indefinite length)
|
// related test case: nonempty UTF-8 string (indefinite length)
|
||||||
std::vector<uint8_t> const vec1{ 0x7f, 0x61, 0x61 };
|
std::vector<uint8_t> const vec1{ 0x7f, 0x61, 0x61 };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec1), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec1),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR string: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// related test case: nonempty array (indefinite length)
|
// related test case: nonempty array (indefinite length)
|
||||||
std::vector<uint8_t> const vec2{ 0x9f, 0x01 };
|
std::vector<uint8_t> const vec2{ 0x9f, 0x01 };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// related test case: nonempty map (indefinite length)
|
// related test case: nonempty map (indefinite length)
|
||||||
std::vector<uint8_t> const vec3{ 0xbf, 0x61, 0x61, 0x01 };
|
std::vector<uint8_t> const vec3{ 0xbf, 0x61, 0x61, 0x01 };
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3),
|
||||||
|
"[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #414 - compare with literal 0)")
|
SECTION("issue #414 - compare with literal 0)")
|
||||||
@@ -1050,30 +1080,24 @@ TEST_CASE("regression tests 1")
|
|||||||
SECTION("issue #416 - Use-of-uninitialized-value (OSS-Fuzz issue 377)")
|
SECTION("issue #416 - Use-of-uninitialized-value (OSS-Fuzz issue 377)")
|
||||||
{
|
{
|
||||||
// original test case
|
// original test case
|
||||||
std::vector<uint8_t> const vec1
|
std::vector<uint8_t> const vec1{ 0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
||||||
{
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71, 0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
|
||||||
0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
|
0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfa };
|
||||||
0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
||||||
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,
|
|
||||||
0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
|
|
||||||
0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
|
|
||||||
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfa
|
|
||||||
};
|
|
||||||
|
|
||||||
json _;
|
json _;
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec1), "[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::from_cbor(vec1),
|
||||||
|
"[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
// related test case: double-precision
|
// related test case: double-precision
|
||||||
std::vector<uint8_t> const vec2
|
std::vector<uint8_t> const vec2{ 0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
||||||
{
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71, 0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
|
||||||
0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
|
0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfb };
|
||||||
0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
CHECK_THROWS_WITH_AS(
|
||||||
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,
|
_ = json::from_cbor(vec2),
|
||||||
0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
|
"[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4",
|
||||||
0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
|
json::parse_error&);
|
||||||
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfb
|
|
||||||
};
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4", json::parse_error&);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)")
|
SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)")
|
||||||
@@ -1117,8 +1141,7 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
SECTION("std::vector")
|
SECTION("std::vector")
|
||||||
{
|
{
|
||||||
auto create = [](const json & j)
|
auto create = [](const json& j) {
|
||||||
{
|
|
||||||
std::vector<int> const v = j;
|
std::vector<int> const v = j;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1129,8 +1152,7 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
SECTION("std::list")
|
SECTION("std::list")
|
||||||
{
|
{
|
||||||
auto create = [](const json & j)
|
auto create = [](const json& j) {
|
||||||
{
|
|
||||||
std::list<int> const v = j;
|
std::list<int> const v = j;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1141,8 +1163,7 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
SECTION("std::forward_list")
|
SECTION("std::forward_list")
|
||||||
{
|
{
|
||||||
auto create = [](const json & j)
|
auto create = [](const json& j) {
|
||||||
{
|
|
||||||
std::forward_list<int> const v = j;
|
std::forward_list<int> const v = j;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1327,11 +1348,8 @@ TEST_CASE("regression tests 1")
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::ifstream is;
|
std::ifstream is;
|
||||||
is.exceptions(
|
is.exceptions(is.exceptions() | std::ios_base::failbit |
|
||||||
is.exceptions()
|
std::ios_base::badbit); // handle different exceptions as 'file not found', 'permission denied'
|
||||||
| std::ios_base::failbit
|
|
||||||
| std::ios_base::badbit
|
|
||||||
); // handle different exceptions as 'file not found', 'permission denied'
|
|
||||||
|
|
||||||
is.open(TEST_DATA_DIRECTORY "/regression/working_file.json");
|
is.open(TEST_DATA_DIRECTORY "/regression/working_file.json");
|
||||||
json _;
|
json _;
|
||||||
@@ -1340,14 +1358,10 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
{
|
{
|
||||||
std::ifstream is;
|
std::ifstream is;
|
||||||
is.exceptions(
|
is.exceptions(is.exceptions() | std::ios_base::failbit |
|
||||||
is.exceptions()
|
std::ios_base::badbit); // handle different exceptions as 'file not found', 'permission denied'
|
||||||
| std::ios_base::failbit
|
|
||||||
| std::ios_base::badbit
|
|
||||||
); // handle different exceptions as 'file not found', 'permission denied'
|
|
||||||
|
|
||||||
is.open(TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json.cbor",
|
is.open(TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json.cbor", std::ios_base::in | std::ios_base::binary);
|
||||||
std::ios_base::in | std::ios_base::binary);
|
|
||||||
json _;
|
json _;
|
||||||
CHECK_NOTHROW(_ = nlohmann::json::from_cbor(is));
|
CHECK_NOTHROW(_ = nlohmann::json::from_cbor(is));
|
||||||
}
|
}
|
||||||
@@ -1363,7 +1377,8 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
SECTION("issue #838 - incorrect parse error with binary data in keys")
|
SECTION("issue #838 - incorrect parse error with binary data in keys")
|
||||||
{
|
{
|
||||||
std::array<uint8_t, 28> key1 = {{ 103, 92, 117, 48, 48, 48, 55, 92, 114, 215, 126, 214, 95, 92, 34, 174, 40, 71, 38, 174, 40, 71, 38, 223, 134, 247, 127, 0 }};
|
std::array<uint8_t, 28> key1 = { { 103, 92, 117, 48, 48, 48, 55, 92, 114, 215, 126, 214, 95, 92,
|
||||||
|
34, 174, 40, 71, 38, 174, 40, 71, 38, 223, 134, 247, 127, 0 } };
|
||||||
std::string const key1_str(reinterpret_cast<char*>(key1.data()));
|
std::string const key1_str(reinterpret_cast<char*>(key1.data()));
|
||||||
json const j = key1_str;
|
json const j = key1_str;
|
||||||
CHECK_THROWS_WITH_AS(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E", json::type_error&);
|
CHECK_THROWS_WITH_AS(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E", json::type_error&);
|
||||||
@@ -1393,27 +1408,17 @@ TEST_CASE("regression tests 1")
|
|||||||
auto p1 = R"([{"op": "move",
|
auto p1 = R"([{"op": "move",
|
||||||
"from": "/one/two/three",
|
"from": "/one/two/three",
|
||||||
"path": "/a/b/c"}])"_json;
|
"path": "/a/b/c"}])"_json;
|
||||||
CHECK_THROWS_WITH_AS(model.patch(p1),
|
CHECK_THROWS_WITH_AS(model.patch(p1), "[json.exception.out_of_range.403] key 'a' not found", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.403] key 'a' not found", json::out_of_range&);
|
|
||||||
|
|
||||||
auto p2 = R"([{"op": "copy",
|
auto p2 = R"([{"op": "copy",
|
||||||
"from": "/one/two/three",
|
"from": "/one/two/three",
|
||||||
"path": "/a/b/c"}])"_json;
|
"path": "/a/b/c"}])"_json;
|
||||||
CHECK_THROWS_WITH_AS(model.patch(p2),
|
CHECK_THROWS_WITH_AS(model.patch(p2), "[json.exception.out_of_range.403] key 'a' not found", json::out_of_range&);
|
||||||
"[json.exception.out_of_range.403] key 'a' not found", json::out_of_range&);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #961 - incorrect parsing of indefinite length CBOR strings")
|
SECTION("issue #961 - incorrect parsing of indefinite length CBOR strings")
|
||||||
{
|
{
|
||||||
std::vector<uint8_t> const v_cbor =
|
std::vector<uint8_t> const v_cbor = { 0x7F, 0x64, 'a', 'b', 'c', 'd', 0x63, '1', '2', '3', 0xFF };
|
||||||
{
|
|
||||||
0x7F,
|
|
||||||
0x64,
|
|
||||||
'a', 'b', 'c', 'd',
|
|
||||||
0x63,
|
|
||||||
'1', '2', '3',
|
|
||||||
0xFF
|
|
||||||
};
|
|
||||||
json j = json::from_cbor(v_cbor);
|
json j = json::from_cbor(v_cbor);
|
||||||
CHECK(j == "abcd123");
|
CHECK(j == "abcd123");
|
||||||
}
|
}
|
||||||
@@ -1453,8 +1458,7 @@ TEST_CASE("regression tests 1")
|
|||||||
)";
|
)";
|
||||||
|
|
||||||
// define parser callback
|
// define parser callback
|
||||||
json::parser_callback_t const cb = [](int /*depth*/, json::parse_event_t event, json & parsed)
|
json::parser_callback_t const cb = [](int /*depth*/, json::parse_event_t event, json& parsed) {
|
||||||
{
|
|
||||||
// skip object elements with key "Thumbnail"
|
// skip object elements with key "Thumbnail"
|
||||||
return !(event == json::parse_event_t::key && parsed == json("Thumbnail"));
|
return !(event == json::parse_event_t::key && parsed == json("Thumbnail"));
|
||||||
};
|
};
|
||||||
@@ -1504,10 +1508,22 @@ TEST_CASE("regression tests, exceptions dependent")
|
|||||||
// the code below fails with Clang on Windows, so we need to exclude it there
|
// the code below fails with Clang on Windows, so we need to exclude it there
|
||||||
#if DOCTEST_CLANG && (defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__))
|
#if DOCTEST_CLANG && (defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__))
|
||||||
#else
|
#else
|
||||||
template <typename T> class array {};
|
template<typename T>
|
||||||
template <typename T> class object {};
|
class array
|
||||||
template <typename T> class string {};
|
{};
|
||||||
template <typename T> class number_integer {};
|
template<typename T>
|
||||||
template <typename T> class number_unsigned {};
|
class object
|
||||||
template <typename T> class number_float {};
|
{};
|
||||||
|
template<typename T>
|
||||||
|
class string
|
||||||
|
{};
|
||||||
|
template<typename T>
|
||||||
|
class number_integer
|
||||||
|
{};
|
||||||
|
template<typename T>
|
||||||
|
class number_unsigned
|
||||||
|
{};
|
||||||
|
template<typename T>
|
||||||
|
class number_float
|
||||||
|
{};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -191,7 +191,9 @@ class my_allocator : public std::allocator<T>
|
|||||||
using std::allocator<T>::allocator;
|
using std::allocator<T>::allocator;
|
||||||
|
|
||||||
my_allocator() = default;
|
my_allocator() = default;
|
||||||
template<class U> my_allocator(const my_allocator<U>& /*unused*/) { }
|
template<class U>
|
||||||
|
my_allocator(const my_allocator<U>& /*unused*/)
|
||||||
|
{}
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
struct rebind
|
struct rebind
|
||||||
@@ -290,9 +292,11 @@ struct for_3204_bar
|
|||||||
};
|
};
|
||||||
|
|
||||||
explicit for_3204_bar(std::function<void(for_3204_foo)> /*unused*/) noexcept // NOLINT(performance-unnecessary-value-param)
|
explicit for_3204_bar(std::function<void(for_3204_foo)> /*unused*/) noexcept // NOLINT(performance-unnecessary-value-param)
|
||||||
: constructed_from(constructed_from_foo) {}
|
: constructed_from(constructed_from_foo)
|
||||||
|
{}
|
||||||
explicit for_3204_bar(std::function<void(json)> /*unused*/) noexcept // NOLINT(performance-unnecessary-value-param)
|
explicit for_3204_bar(std::function<void(json)> /*unused*/) noexcept // NOLINT(performance-unnecessary-value-param)
|
||||||
: constructed_from(constructed_from_json) {}
|
: constructed_from(constructed_from_json)
|
||||||
|
{}
|
||||||
|
|
||||||
constructed_from_t constructed_from = constructed_from_none;
|
constructed_from_t constructed_from = constructed_from_none;
|
||||||
};
|
};
|
||||||
@@ -303,7 +307,10 @@ struct for_3204_bar
|
|||||||
|
|
||||||
struct for_3333 final
|
struct for_3333 final
|
||||||
{
|
{
|
||||||
for_3333(int x_ = 0, int y_ = 0) : x(x_), y(y_) {}
|
for_3333(int x_ = 0, int y_ = 0)
|
||||||
|
: x(x_)
|
||||||
|
, y(y_)
|
||||||
|
{}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
for_3333(const T& /*unused*/)
|
for_3333(const T& /*unused*/)
|
||||||
@@ -359,8 +366,7 @@ TEST_CASE("regression tests 2")
|
|||||||
]
|
]
|
||||||
})";
|
})";
|
||||||
|
|
||||||
const json::parser_callback_t cb = [&](int /*level*/, json::parse_event_t event, json & parsed) noexcept
|
const json::parser_callback_t cb = [&](int /*level*/, json::parse_event_t event, json& parsed) noexcept {
|
||||||
{
|
|
||||||
// skip uninteresting events
|
// skip uninteresting events
|
||||||
if (event == json::parse_event_t::value && !parsed.is_primitive())
|
if (event == json::parse_event_t::value && !parsed.is_primitive())
|
||||||
{
|
{
|
||||||
@@ -426,14 +432,7 @@ TEST_CASE("regression tests 2")
|
|||||||
|
|
||||||
using it_type = decltype(p1.begin());
|
using it_type = decltype(p1.begin());
|
||||||
|
|
||||||
std::set_difference(
|
std::set_difference(p1.begin(), p1.end(), p2.begin(), p2.end(), std::inserter(diffs, diffs.end()), [&](const it_type& e1, const it_type& e2) -> bool {
|
||||||
p1.begin(),
|
|
||||||
p1.end(),
|
|
||||||
p2.begin(),
|
|
||||||
p2.end(),
|
|
||||||
std::inserter(diffs, diffs.end()),
|
|
||||||
[&](const it_type & e1, const it_type & e2) -> bool
|
|
||||||
{
|
|
||||||
using comper_pair = std::pair<std::string, decltype(e1.value())>; // Trying to avoid unneeded copy
|
using comper_pair = std::pair<std::string, decltype(e1.value())>; // Trying to avoid unneeded copy
|
||||||
return comper_pair(e1.key(), e1.value()) < comper_pair(e2.key(), e2.value()); // Using pair comper
|
return comper_pair(e1.key(), e1.value()) < comper_pair(e2.key(), e2.value()); // Using pair comper
|
||||||
});
|
});
|
||||||
@@ -451,15 +450,13 @@ TEST_CASE("regression tests 2")
|
|||||||
SECTION("issue #1299 - compile error in from_json converting to container "
|
SECTION("issue #1299 - compile error in from_json converting to container "
|
||||||
"with std::pair")
|
"with std::pair")
|
||||||
{
|
{
|
||||||
const json j =
|
const json j = {
|
||||||
{
|
|
||||||
{ "1", { { "a", "testa_1" }, { "b", "testb_1" } } },
|
{ "1", { { "a", "testa_1" }, { "b", "testb_1" } } },
|
||||||
{ "2", { { "a", "testa_2" }, { "b", "testb_2" } } },
|
{ "2", { { "a", "testa_2" }, { "b", "testb_2" } } },
|
||||||
{ "3", { { "a", "testa_3" }, { "b", "testb_3" } } },
|
{ "3", { { "a", "testa_3" }, { "b", "testb_3" } } },
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<std::string, Data> expected
|
std::map<std::string, Data> expected{
|
||||||
{
|
|
||||||
{ "1", { "testa_1", "testb_1" } },
|
{ "1", { "testa_1", "testb_1" } },
|
||||||
{ "2", { "testa_2", "testb_2" } },
|
{ "2", { "testa_2", "testb_2" } },
|
||||||
{ "3", { "testa_3", "testb_3" } },
|
{ "3", { "testa_3", "testb_3" } },
|
||||||
@@ -507,9 +504,11 @@ TEST_CASE("regression tests 2")
|
|||||||
SECTION("test case in issue #1445")
|
SECTION("test case in issue #1445")
|
||||||
{
|
{
|
||||||
nlohmann::json dump_test;
|
nlohmann::json dump_test;
|
||||||
const std::array<int, 108> data =
|
const std::array<int, 108> data = {
|
||||||
{
|
{ 109, 108, 103, 125, -122, -53, 115, 18, 3, 0, 102, 19, 1, 15, -110, 13, -3, -1, -81, 32, 2, 0, 0, 0, 0, 0, 0,
|
||||||
{109, 108, 103, 125, -122, -53, 115, 18, 3, 0, 102, 19, 1, 15, -110, 13, -3, -1, -81, 32, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -80, 2, 0, 0, 96, -118, 46, -116, 46, 109, -84, -87, 108, 14, 109, -24, -83, 13, -18, -51, -83, -52, -115, 14, 6, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 3, 0, 0, 0, 35, -74, -73, 55, 57, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, -96, -54, -28, -26}
|
0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -80, 2, 0, 0, 96, -118, 46, -116, 46, 109, -84, -87, 108, 14,
|
||||||
|
109, -24, -83, 13, -18, -51, -83, -52, -115, 14, 6, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 3, 0, 0,
|
||||||
|
0, 35, -74, -73, 55, 57, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, -96, -54, -28, -26 }
|
||||||
};
|
};
|
||||||
std::string s;
|
std::string s;
|
||||||
for (const int i : data)
|
for (const int i : data)
|
||||||
@@ -607,10 +606,10 @@ TEST_CASE("regression tests 2")
|
|||||||
|
|
||||||
SECTION("issue #2067 - cannot serialize binary data to text JSON")
|
SECTION("issue #2067 - cannot serialize binary data to text JSON")
|
||||||
{
|
{
|
||||||
const std::array<unsigned char, 23> data = {{0x81, 0xA4, 0x64, 0x61, 0x74, 0x61, 0xC4, 0x0F, 0x33, 0x30, 0x30, 0x32, 0x33, 0x34, 0x30, 0x31, 0x30, 0x37, 0x30, 0x35, 0x30, 0x31, 0x30}};
|
const std::array<unsigned char, 23> data = { { 0x81, 0xA4, 0x64, 0x61, 0x74, 0x61, 0xC4, 0x0F, 0x33, 0x30, 0x30, 0x32,
|
||||||
|
0x33, 0x34, 0x30, 0x31, 0x30, 0x37, 0x30, 0x35, 0x30, 0x31, 0x30 } };
|
||||||
const json j = json::from_msgpack(data.data(), data.size());
|
const json j = json::from_msgpack(data.data(), data.size());
|
||||||
CHECK_NOTHROW(
|
CHECK_NOTHROW(j.dump(4, // Indent
|
||||||
j.dump(4, // Indent
|
|
||||||
' ', // Indent char
|
' ', // Indent char
|
||||||
false, // Ensure ascii
|
false, // Ensure ascii
|
||||||
json::error_handler_t::strict // Error
|
json::error_handler_t::strict // Error
|
||||||
@@ -628,19 +627,7 @@ TEST_CASE("regression tests 2")
|
|||||||
|
|
||||||
SECTION("issue #2293 - eof doesn't cause parsing to stop")
|
SECTION("issue #2293 - eof doesn't cause parsing to stop")
|
||||||
{
|
{
|
||||||
const std::vector<uint8_t> data =
|
const std::vector<uint8_t> data = { 0x7B, 0x6F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x4F, 0x42 };
|
||||||
{
|
|
||||||
0x7B,
|
|
||||||
0x6F,
|
|
||||||
0x62,
|
|
||||||
0x6A,
|
|
||||||
0x65,
|
|
||||||
0x63,
|
|
||||||
0x74,
|
|
||||||
0x20,
|
|
||||||
0x4F,
|
|
||||||
0x42
|
|
||||||
};
|
|
||||||
const json result = json::from_cbor(data, true, false);
|
const json result = json::from_cbor(data, true, false);
|
||||||
CHECK(result.is_discarded());
|
CHECK(result.is_discarded());
|
||||||
}
|
}
|
||||||
@@ -655,9 +642,7 @@ TEST_CASE("regression tests 2")
|
|||||||
auto jsonAnimals_parsed = nlohmann::ordered_json::parse(jsonAnimals.dump());
|
auto jsonAnimals_parsed = nlohmann::ordered_json::parse(jsonAnimals.dump());
|
||||||
CHECK(jsonAnimals == jsonAnimals_parsed);
|
CHECK(jsonAnimals == jsonAnimals_parsed);
|
||||||
|
|
||||||
const std::vector<std::pair<std::string, int64_t>> intData = {std::make_pair("aaaa", 11),
|
const std::vector<std::pair<std::string, int64_t>> intData = { std::make_pair("aaaa", 11), std::make_pair("bbb", 222) };
|
||||||
std::make_pair("bbb", 222)
|
|
||||||
};
|
|
||||||
nlohmann::ordered_json jsonObj;
|
nlohmann::ordered_json jsonObj;
|
||||||
for (const auto& data : intData)
|
for (const auto& data : intData)
|
||||||
{
|
{
|
||||||
@@ -787,7 +772,8 @@ TEST_CASE("regression tests 2")
|
|||||||
sax_no_exception sax(j);
|
sax_no_exception sax(j);
|
||||||
|
|
||||||
CHECK(!json::sax_parse("xyz", &sax));
|
CHECK(!json::sax_parse("xyz", &sax));
|
||||||
CHECK(*sax_no_exception::error_string == "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'");
|
CHECK(*sax_no_exception::error_string ==
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'");
|
||||||
delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)
|
delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -858,10 +844,12 @@ TEST_CASE("regression tests 2")
|
|||||||
|
|
||||||
CHECK(j.dump() == "[1,2,4]");
|
CHECK(j.dump() == "[1,2,4]");
|
||||||
|
|
||||||
j.erase(std::remove_if(j.begin(), j.end(), [](const ordered_json & val)
|
j.erase(std::remove_if(j.begin(),
|
||||||
{
|
j.end(),
|
||||||
|
[](const ordered_json& val) {
|
||||||
return val == 2;
|
return val == 2;
|
||||||
}), j.end());
|
}),
|
||||||
|
j.end());
|
||||||
|
|
||||||
CHECK(j.dump() == "[1,4]");
|
CHECK(j.dump() == "[1,4]");
|
||||||
}
|
}
|
||||||
@@ -926,11 +914,7 @@ TEST_CASE("regression tests 2")
|
|||||||
|
|
||||||
SECTION("issue #3333 - Ambiguous conversion from nlohmann::basic_json<> to custom class")
|
SECTION("issue #3333 - Ambiguous conversion from nlohmann::basic_json<> to custom class")
|
||||||
{
|
{
|
||||||
const json j
|
const json j{ { "x", 1 }, { "y", 2 } };
|
||||||
{
|
|
||||||
{"x", 1},
|
|
||||||
{"y", 2}
|
|
||||||
};
|
|
||||||
for_3333 p = j;
|
for_3333 p = j;
|
||||||
|
|
||||||
CHECK(p.x == 1);
|
CHECK(p.x == 1);
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
TEST_CASE("serialization")
|
TEST_CASE("serialization")
|
||||||
{
|
{
|
||||||
@@ -31,8 +31,7 @@ TEST_CASE("serialization")
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
const json j = { "foo", 1, 2, 3, false, { { "one", 1 } } };
|
const json j = { "foo", 1, 2, 3, false, { { "one", 1 } } };
|
||||||
ss << std::setw(4) << j;
|
ss << std::setw(4) << j;
|
||||||
CHECK(ss.str() ==
|
CHECK(ss.str() == "[\n \"foo\",\n 1,\n 2,\n 3,\n false,\n {\n \"one\": 1\n }\n]");
|
||||||
"[\n \"foo\",\n 1,\n 2,\n 3,\n false,\n {\n \"one\": 1\n }\n]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("given fill")
|
SECTION("given fill")
|
||||||
@@ -40,8 +39,7 @@ TEST_CASE("serialization")
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
const json j = { "foo", 1, 2, 3, false, { { "one", 1 } } };
|
const json j = { "foo", 1, 2, 3, false, { { "one", 1 } } };
|
||||||
ss << std::setw(1) << std::setfill('\t') << j;
|
ss << std::setw(1) << std::setfill('\t') << j;
|
||||||
CHECK(ss.str() ==
|
CHECK(ss.str() == "[\n\t\"foo\",\n\t1,\n\t2,\n\t3,\n\tfalse,\n\t{\n\t\t\"one\": 1\n\t}\n]");
|
||||||
"[\n\t\"foo\",\n\t1,\n\t2,\n\t3,\n\tfalse,\n\t{\n\t\t\"one\": 1\n\t}\n]");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,8 +59,7 @@ TEST_CASE("serialization")
|
|||||||
const json j = { "foo", 1, 2, 3, false, { { "one", 1 } } };
|
const json j = { "foo", 1, 2, 3, false, { { "one", 1 } } };
|
||||||
ss.width(4);
|
ss.width(4);
|
||||||
j >> ss;
|
j >> ss;
|
||||||
CHECK(ss.str() ==
|
CHECK(ss.str() == "[\n \"foo\",\n 1,\n 2,\n 3,\n false,\n {\n \"one\": 1\n }\n]");
|
||||||
"[\n \"foo\",\n 1,\n 2,\n 3,\n false,\n {\n \"one\": 1\n }\n]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("given fill")
|
SECTION("given fill")
|
||||||
@@ -72,8 +69,7 @@ TEST_CASE("serialization")
|
|||||||
ss.width(1);
|
ss.width(1);
|
||||||
ss.fill('\t');
|
ss.fill('\t');
|
||||||
j >> ss;
|
j >> ss;
|
||||||
CHECK(ss.str() ==
|
CHECK(ss.str() == "[\n\t\"foo\",\n\t1,\n\t2,\n\t3,\n\tfalse,\n\t{\n\t\t\"one\": 1\n\t}\n]");
|
||||||
"[\n\t\"foo\",\n\t1,\n\t2,\n\t3,\n\tfalse,\n\t{\n\t\t\"one\": 1\n\t}\n]");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +80,9 @@ TEST_CASE("serialization")
|
|||||||
const json j = "ä\xA9ü";
|
const json j = "ä\xA9ü";
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9", json::type_error&);
|
CHECK_THROWS_WITH_AS(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9", json::type_error&);
|
||||||
CHECK_THROWS_WITH_AS(j.dump(1, ' ', false, json::error_handler_t::strict), "[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9", json::type_error&);
|
CHECK_THROWS_WITH_AS(j.dump(1, ' ', false, json::error_handler_t::strict),
|
||||||
|
"[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9",
|
||||||
|
json::type_error&);
|
||||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::ignore) == "\"äü\"");
|
CHECK(j.dump(-1, ' ', false, json::error_handler_t::ignore) == "\"äü\"");
|
||||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::replace) == "\"ä\xEF\xBF\xBDü\"");
|
CHECK(j.dump(-1, ' ', false, json::error_handler_t::replace) == "\"ä\xEF\xBF\xBDü\"");
|
||||||
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"\\u00e4\\ufffd\\u00fc\"");
|
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"\\u00e4\\ufffd\\u00fc\"");
|
||||||
@@ -118,41 +116,108 @@ TEST_CASE("serialization")
|
|||||||
// https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf
|
// https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf
|
||||||
// Section 3.9 -- U+FFFD Substitution of Maximal Subparts
|
// Section 3.9 -- U+FFFD Substitution of Maximal Subparts
|
||||||
|
|
||||||
auto test = [&](std::string const & input, std::string const & expected)
|
auto test = [&](std::string const& input, std::string const& expected) {
|
||||||
{
|
|
||||||
const json j = input;
|
const json j = input;
|
||||||
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"" + expected + "\"");
|
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"" + expected + "\"");
|
||||||
};
|
};
|
||||||
|
|
||||||
test("\xC2", "\\ufffd");
|
test("\xC2", "\\ufffd");
|
||||||
test("\xC2\x41\x42", "\\ufffd" "\x41" "\x42");
|
test("\xC2\x41\x42",
|
||||||
test("\xC2\xF4", "\\ufffd" "\\ufffd");
|
"\\ufffd"
|
||||||
|
"\x41"
|
||||||
|
"\x42");
|
||||||
|
test("\xC2\xF4",
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd");
|
||||||
|
|
||||||
test("\xF0\x80\x80\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
test("\xF0\x80\x80\x41",
|
||||||
test("\xF1\x80\x80\x41", "\\ufffd" "\x41");
|
"\\ufffd"
|
||||||
test("\xF2\x80\x80\x41", "\\ufffd" "\x41");
|
"\\ufffd"
|
||||||
test("\xF3\x80\x80\x41", "\\ufffd" "\x41");
|
"\\ufffd"
|
||||||
test("\xF4\x80\x80\x41", "\\ufffd" "\x41");
|
"\x41");
|
||||||
test("\xF5\x80\x80\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
test("\xF1\x80\x80\x41",
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
|
test("\xF2\x80\x80\x41",
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
|
test("\xF3\x80\x80\x41",
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
|
test("\xF4\x80\x80\x41",
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
|
test("\xF5\x80\x80\x41",
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
|
|
||||||
test("\xF0\x90\x80\x41", "\\ufffd" "\x41");
|
test("\xF0\x90\x80\x41",
|
||||||
test("\xF1\x90\x80\x41", "\\ufffd" "\x41");
|
"\\ufffd"
|
||||||
test("\xF2\x90\x80\x41", "\\ufffd" "\x41");
|
"\x41");
|
||||||
test("\xF3\x90\x80\x41", "\\ufffd" "\x41");
|
test("\xF1\x90\x80\x41",
|
||||||
test("\xF4\x90\x80\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
"\\ufffd"
|
||||||
test("\xF5\x90\x80\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
"\x41");
|
||||||
|
test("\xF2\x90\x80\x41",
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
|
test("\xF3\x90\x80\x41",
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
|
test("\xF4\x90\x80\x41",
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
|
test("\xF5\x90\x80\x41",
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
|
|
||||||
test("\xC0\xAF\xE0\x80\xBF\xF0\x81\x82\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
test("\xC0\xAF\xE0\x80\xBF\xF0\x81\x82\x41",
|
||||||
test("\xED\xA0\x80\xED\xBF\xBF\xED\xAF\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
"\\ufffd"
|
||||||
test("\xF4\x91\x92\x93\xFF\x41\x80\xBF\x42", "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\x41" "\\ufffd""\\ufffd" "\x42");
|
"\\ufffd"
|
||||||
test("\xE1\x80\xE2\xF0\x91\x92\xF1\xBF\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
|
test("\xED\xA0\x80\xED\xBF\xBF\xED\xAF\x41",
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
|
test("\xF4\x91\x92\x93\xFF\x41\x80\xBF\x42",
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\x42");
|
||||||
|
test("\xE1\x80\xE2\xF0\x91\x92\xF1\xBF\x41",
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\\ufffd"
|
||||||
|
"\x41");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("to_string")
|
SECTION("to_string")
|
||||||
{
|
{
|
||||||
auto test = [&](std::string const & input, std::string const & expected)
|
auto test = [&](std::string const& input, std::string const& expected) {
|
||||||
{
|
|
||||||
using std::to_string;
|
using std::to_string;
|
||||||
const json j = input;
|
const json j = input;
|
||||||
CHECK(to_string(j) == "\"" + expected + "\"");
|
CHECK(to_string(j) == "\"" + expected + "\"");
|
||||||
|
|||||||
+41
-104
@@ -11,8 +11,8 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
TEST_CASE("compliance tests from json.org")
|
TEST_CASE("compliance tests from json.org")
|
||||||
{
|
{
|
||||||
@@ -20,9 +20,7 @@ TEST_CASE("compliance tests from json.org")
|
|||||||
|
|
||||||
SECTION("expected failures")
|
SECTION("expected failures")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { //TEST_DATA_DIRECTORY "/json_tests/fail1.json",
|
||||||
{
|
|
||||||
//TEST_DATA_DIRECTORY "/json_tests/fail1.json",
|
|
||||||
TEST_DATA_DIRECTORY "/json_tests/fail2.json",
|
TEST_DATA_DIRECTORY "/json_tests/fail2.json",
|
||||||
TEST_DATA_DIRECTORY "/json_tests/fail3.json",
|
TEST_DATA_DIRECTORY "/json_tests/fail3.json",
|
||||||
TEST_DATA_DIRECTORY "/json_tests/fail4.json",
|
TEST_DATA_DIRECTORY "/json_tests/fail4.json",
|
||||||
@@ -54,8 +52,7 @@ TEST_CASE("compliance tests from json.org")
|
|||||||
TEST_DATA_DIRECTORY "/json_tests/fail30.json",
|
TEST_DATA_DIRECTORY "/json_tests/fail30.json",
|
||||||
TEST_DATA_DIRECTORY "/json_tests/fail31.json",
|
TEST_DATA_DIRECTORY "/json_tests/fail31.json",
|
||||||
TEST_DATA_DIRECTORY "/json_tests/fail32.json",
|
TEST_DATA_DIRECTORY "/json_tests/fail32.json",
|
||||||
TEST_DATA_DIRECTORY "/json_tests/fail33.json"
|
TEST_DATA_DIRECTORY "/json_tests/fail33.json" })
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -69,8 +66,7 @@ TEST_CASE("compliance tests from json.org")
|
|||||||
// these tests fail above, because the parser does not end on EOF;
|
// these tests fail above, because the parser does not end on EOF;
|
||||||
// they succeed when the operator>> is used, because it does not
|
// they succeed when the operator>> is used, because it does not
|
||||||
// have this constraint
|
// have this constraint
|
||||||
for (const auto* filename :
|
for (const auto* filename : {
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/json_tests/fail7.json",
|
TEST_DATA_DIRECTORY "/json_tests/fail7.json",
|
||||||
TEST_DATA_DIRECTORY "/json_tests/fail8.json",
|
TEST_DATA_DIRECTORY "/json_tests/fail8.json",
|
||||||
TEST_DATA_DIRECTORY "/json_tests/fail10.json",
|
TEST_DATA_DIRECTORY "/json_tests/fail10.json",
|
||||||
@@ -86,11 +82,7 @@ TEST_CASE("compliance tests from json.org")
|
|||||||
SECTION("expected passes")
|
SECTION("expected passes")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename :
|
||||||
{
|
{ TEST_DATA_DIRECTORY "/json_tests/pass1.json", TEST_DATA_DIRECTORY "/json_tests/pass2.json", TEST_DATA_DIRECTORY "/json_tests/pass3.json" })
|
||||||
TEST_DATA_DIRECTORY "/json_tests/pass1.json",
|
|
||||||
TEST_DATA_DIRECTORY "/json_tests/pass2.json",
|
|
||||||
TEST_DATA_DIRECTORY "/json_tests/pass3.json"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -106,8 +98,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
|
|||||||
|
|
||||||
SECTION("doubles")
|
SECTION("doubles")
|
||||||
{
|
{
|
||||||
auto TEST_DOUBLE = [](const std::string & json_string, const double expected)
|
auto TEST_DOUBLE = [](const std::string& json_string, const double expected) {
|
||||||
{
|
|
||||||
CAPTURE(json_string)
|
CAPTURE(json_string)
|
||||||
CAPTURE(expected)
|
CAPTURE(expected)
|
||||||
CHECK(json::parse(json_string)[0].get<double>() == Approx(expected));
|
CHECK(json::parse(json_string)[0].get<double>() == Approx(expected));
|
||||||
@@ -147,8 +138,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
|
|||||||
0.9868011474609375); // https://github.com/miloyip/rapidjson/issues/120
|
0.9868011474609375); // https://github.com/miloyip/rapidjson/issues/120
|
||||||
TEST_DOUBLE("[123e34]", 123e34); // Fast Path Cases In Disguise
|
TEST_DOUBLE("[123e34]", 123e34); // Fast Path Cases In Disguise
|
||||||
TEST_DOUBLE("[45913141877270640000.0]", 45913141877270640000.0);
|
TEST_DOUBLE("[45913141877270640000.0]", 45913141877270640000.0);
|
||||||
TEST_DOUBLE("[2.2250738585072011e-308]",
|
TEST_DOUBLE("[2.2250738585072011e-308]", 2.2250738585072011e-308);
|
||||||
2.2250738585072011e-308);
|
|
||||||
//TEST_DOUBLE("[1e-00011111111111]", 0.0);
|
//TEST_DOUBLE("[1e-00011111111111]", 0.0);
|
||||||
//TEST_DOUBLE("[-1e-00011111111111]", -0.0);
|
//TEST_DOUBLE("[-1e-00011111111111]", -0.0);
|
||||||
TEST_DOUBLE("[1e-214748363]", 0.0);
|
TEST_DOUBLE("[1e-214748363]", 0.0);
|
||||||
@@ -160,15 +150,12 @@ TEST_CASE("compliance tests from nativejson-benchmark")
|
|||||||
// abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... ¡Á 10^-324
|
// abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... ¡Á 10^-324
|
||||||
// abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... ¡Á 10 ^ -324
|
// abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... ¡Á 10 ^ -324
|
||||||
// So 2.2250738585072012e-308 should round to 2^-1022 = 2.2250738585072014e-308
|
// So 2.2250738585072012e-308 should round to 2^-1022 = 2.2250738585072014e-308
|
||||||
TEST_DOUBLE("[2.2250738585072012e-308]",
|
TEST_DOUBLE("[2.2250738585072012e-308]", 2.2250738585072014e-308);
|
||||||
2.2250738585072014e-308);
|
|
||||||
|
|
||||||
// More closer to normal/subnormal boundary
|
// More closer to normal/subnormal boundary
|
||||||
// boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... ¡Á 10^-308
|
// boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... ¡Á 10^-308
|
||||||
TEST_DOUBLE("[2.22507385850720113605740979670913197593481954635164564e-308]",
|
TEST_DOUBLE("[2.22507385850720113605740979670913197593481954635164564e-308]", 2.2250738585072009e-308);
|
||||||
2.2250738585072009e-308);
|
TEST_DOUBLE("[2.22507385850720113605740979670913197593481954635164565e-308]", 2.2250738585072014e-308);
|
||||||
TEST_DOUBLE("[2.22507385850720113605740979670913197593481954635164565e-308]",
|
|
||||||
2.2250738585072014e-308);
|
|
||||||
|
|
||||||
// 1.0 is in (1.0 - 2^-54, 1.0 + 2^-53)
|
// 1.0 is in (1.0 - 2^-54, 1.0 + 2^-53)
|
||||||
// 1.0 - 2^-54 = 0.999999999999999944488848768742172978818416595458984375
|
// 1.0 - 2^-54 = 0.999999999999999944488848768742172978818416595458984375
|
||||||
@@ -202,16 +189,11 @@ TEST_CASE("compliance tests from nativejson-benchmark")
|
|||||||
TEST_DOUBLE("[1014120480182583464902367222169599999e-5]", 10141204801825834086073718800384.0);
|
TEST_DOUBLE("[1014120480182583464902367222169599999e-5]", 10141204801825834086073718800384.0);
|
||||||
TEST_DOUBLE("[1014120480182583464902367222169600001e-5]", 10141204801825835211973625643008.0);
|
TEST_DOUBLE("[1014120480182583464902367222169600001e-5]", 10141204801825835211973625643008.0);
|
||||||
|
|
||||||
TEST_DOUBLE("[5708990770823838890407843763683279797179383808]",
|
TEST_DOUBLE("[5708990770823838890407843763683279797179383808]", 5708990770823838890407843763683279797179383808.0);
|
||||||
5708990770823838890407843763683279797179383808.0);
|
TEST_DOUBLE("[5708990770823839524233143877797980545530986496]", 5708990770823839524233143877797980545530986496.0);
|
||||||
TEST_DOUBLE("[5708990770823839524233143877797980545530986496]",
|
TEST_DOUBLE("[5708990770823839207320493820740630171355185152]", 5708990770823839524233143877797980545530986496.0);
|
||||||
5708990770823839524233143877797980545530986496.0);
|
TEST_DOUBLE("[5708990770823839207320493820740630171355185151999e-3]", 5708990770823838890407843763683279797179383808.0);
|
||||||
TEST_DOUBLE("[5708990770823839207320493820740630171355185152]",
|
TEST_DOUBLE("[5708990770823839207320493820740630171355185152001e-3]", 5708990770823839524233143877797980545530986496.0);
|
||||||
5708990770823839524233143877797980545530986496.0);
|
|
||||||
TEST_DOUBLE("[5708990770823839207320493820740630171355185151999e-3]",
|
|
||||||
5708990770823838890407843763683279797179383808.0);
|
|
||||||
TEST_DOUBLE("[5708990770823839207320493820740630171355185152001e-3]",
|
|
||||||
5708990770823839524233143877797980545530986496.0);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string n1e308(312, '0'); // '1' followed by 308 '0'
|
std::string n1e308(312, '0'); // '1' followed by 308 '0'
|
||||||
@@ -223,8 +205,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cover trimming
|
// Cover trimming
|
||||||
TEST_DOUBLE(
|
TEST_DOUBLE("[2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508"
|
||||||
"[2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508"
|
|
||||||
"7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012"
|
"7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012"
|
||||||
"9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306"
|
"9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306"
|
||||||
"6665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505"
|
"6665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505"
|
||||||
@@ -238,8 +219,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
|
|||||||
|
|
||||||
SECTION("strings")
|
SECTION("strings")
|
||||||
{
|
{
|
||||||
auto TEST_STRING = [](const std::string & json_string, const std::string & expected)
|
auto TEST_STRING = [](const std::string& json_string, const std::string& expected) {
|
||||||
{
|
|
||||||
CAPTURE(json_string)
|
CAPTURE(json_string)
|
||||||
CAPTURE(expected)
|
CAPTURE(expected)
|
||||||
CHECK(json::parse(json_string)[0].get<std::string>() == expected);
|
CHECK(json::parse(json_string)[0].get<std::string>() == expected);
|
||||||
@@ -260,8 +240,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
|
|||||||
{
|
{
|
||||||
// test cases are from https://github.com/miloyip/nativejson-benchmark/tree/master/test/data/roundtrip
|
// test cases are from https://github.com/miloyip/nativejson-benchmark/tree/master/test/data/roundtrip
|
||||||
|
|
||||||
for (const auto* filename :
|
for (const auto* filename : {
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip01.json",
|
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip01.json",
|
||||||
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip02.json",
|
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip02.json",
|
||||||
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip03.json",
|
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip03.json",
|
||||||
@@ -298,8 +277,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
|
|||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
std::string json_string( (std::istreambuf_iterator<char>(f) ),
|
std::string json_string((std::istreambuf_iterator<char>(f)), (std::istreambuf_iterator<char>()));
|
||||||
(std::istreambuf_iterator<char>()) );
|
|
||||||
|
|
||||||
CAPTURE(json_string)
|
CAPTURE(json_string)
|
||||||
const json j = json::parse(json_string);
|
const json j = json::parse(json_string);
|
||||||
@@ -475,9 +453,7 @@ TEST_CASE("nst's JSONTestSuite")
|
|||||||
{
|
{
|
||||||
SECTION("y")
|
SECTION("y")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_arraysWithSpaces.json",
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_arraysWithSpaces.json",
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_empty-string.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_empty-string.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_empty.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_empty.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_ending_with_newline.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_ending_with_newline.json",
|
||||||
@@ -572,9 +548,7 @@ TEST_CASE("nst's JSONTestSuite")
|
|||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_string_empty.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_string_empty.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_trailing_newline.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_trailing_newline.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_true_in_array.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_true_in_array.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_whitespace_array.json"
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_whitespace_array.json" })
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -585,9 +559,7 @@ TEST_CASE("nst's JSONTestSuite")
|
|||||||
|
|
||||||
SECTION("n")
|
SECTION("n")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_1_true_without_comma.json",
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_1_true_without_comma.json",
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_a_invalid_utf8.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_a_invalid_utf8.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_colon_instead_of_comma.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_colon_instead_of_comma.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_comma_after_close.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_comma_after_close.json",
|
||||||
@@ -781,9 +753,7 @@ TEST_CASE("nst's JSONTestSuite")
|
|||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_unclosed_object.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_unclosed_object.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_unicode-identifier.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_unicode-identifier.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_whitespace_U+2060_word_joiner.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_whitespace_U+2060_word_joiner.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_whitespace_formfeed.json"
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_whitespace_formfeed.json" })
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -797,9 +767,7 @@ TEST_CASE("nst's JSONTestSuite")
|
|||||||
// these tests fail above, because the parser does not end on EOF;
|
// these tests fail above, because the parser does not end on EOF;
|
||||||
// they succeed when the operator>> is used, because it does not
|
// they succeed when the operator>> is used, because it does not
|
||||||
// have this constraint
|
// have this constraint
|
||||||
for (const auto* filename :
|
for (const auto* filename : { TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_comma_after_close.json",
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_comma_after_close.json",
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_extra_close.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_extra_close.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_trailing_comment.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_trailing_comment.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_trailing_comment_open.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_trailing_comment_open.json",
|
||||||
@@ -814,9 +782,7 @@ TEST_CASE("nst's JSONTestSuite")
|
|||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_number_with_trailing_garbage.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_number_with_trailing_garbage.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_object_followed_by_closing_object.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_object_followed_by_closing_object.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_object_with_trailing_garbage.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_object_with_trailing_garbage.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_trailing_#.json"
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_trailing_#.json" })
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -827,9 +793,7 @@ TEST_CASE("nst's JSONTestSuite")
|
|||||||
|
|
||||||
SECTION("i -> y")
|
SECTION("i -> y")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { // we do not pose a limit on nesting
|
||||||
{
|
|
||||||
// we do not pose a limit on nesting
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_structure_500_nested_arrays.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_structure_500_nested_arrays.json",
|
||||||
// we silently ignore BOMs
|
// we silently ignore BOMs
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_structure_UTF-8_BOM_empty_object.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_structure_UTF-8_BOM_empty_object.json",
|
||||||
@@ -837,9 +801,7 @@ TEST_CASE("nst's JSONTestSuite")
|
|||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_unicode_U+10FFFE_nonchar.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_unicode_U+10FFFE_nonchar.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_unicode_U+1FFFE_nonchar.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_unicode_U+1FFFE_nonchar.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_unicode_U+FDD0_nonchar.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_unicode_U+FDD0_nonchar.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_unicode_U+FFFE_nonchar.json"
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_unicode_U+FFFE_nonchar.json" })
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -851,15 +813,11 @@ TEST_CASE("nst's JSONTestSuite")
|
|||||||
// numbers that overflow during parsing
|
// numbers that overflow during parsing
|
||||||
SECTION("i/y -> n (out of range)")
|
SECTION("i/y -> n (out of range)")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_number_neg_int_huge_exp.json",
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_number_neg_int_huge_exp.json",
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_number_pos_double_huge_exp.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_number_pos_double_huge_exp.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json"
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json" })
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -870,9 +828,7 @@ TEST_CASE("nst's JSONTestSuite")
|
|||||||
|
|
||||||
SECTION("i -> n")
|
SECTION("i -> n")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_object_key_lone_2nd_surrogate.json",
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_object_key_lone_2nd_surrogate.json",
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_1st_surrogate_but_2nd_missing.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_1st_surrogate_but_2nd_missing.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_1st_valid_surrogate_2nd_invalid.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_1st_valid_surrogate_2nd_invalid.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_UTF-16_invalid_lonely_surrogate.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_UTF-16_invalid_lonely_surrogate.json",
|
||||||
@@ -884,9 +840,7 @@ TEST_CASE("nst's JSONTestSuite")
|
|||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_inverted_surrogates_U+1D11E.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_inverted_surrogates_U+1D11E.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_lone_second_surrogate.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_lone_second_surrogate.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_not_in_unicode_range.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_not_in_unicode_range.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_truncated-utf-8.json"
|
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/i_string_truncated-utf-8.json" })
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -903,9 +857,7 @@ TEST_CASE("nst's JSONTestSuite (2)")
|
|||||||
{
|
{
|
||||||
SECTION("y")
|
SECTION("y")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_arraysWithSpaces.json",
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_arraysWithSpaces.json",
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_empty-string.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_empty-string.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_empty.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_empty.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_ending_with_newline.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_ending_with_newline.json",
|
||||||
@@ -999,9 +951,7 @@ TEST_CASE("nst's JSONTestSuite (2)")
|
|||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_string_empty.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_string_empty.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_trailing_newline.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_trailing_newline.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_true_in_array.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_true_in_array.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_whitespace_array.json"
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_whitespace_array.json" })
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -1015,8 +965,7 @@ TEST_CASE("nst's JSONTestSuite (2)")
|
|||||||
SECTION("n")
|
SECTION("n")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename :
|
||||||
{
|
{ TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_1_true_without_comma.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_1_true_without_comma.json",
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_a_invalid_utf8.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_a_invalid_utf8.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_colon_instead_of_comma.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_colon_instead_of_comma.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_comma_after_close.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_comma_after_close.json",
|
||||||
@@ -1201,9 +1150,7 @@ TEST_CASE("nst's JSONTestSuite (2)")
|
|||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unclosed_object.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unclosed_object.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unicode-identifier.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unicode-identifier.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_whitespace_U+2060_word_joiner.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_whitespace_U+2060_word_joiner.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_whitespace_formfeed.json"
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_whitespace_formfeed.json" })
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -1216,12 +1163,8 @@ TEST_CASE("nst's JSONTestSuite (2)")
|
|||||||
|
|
||||||
SECTION("n (previously overflowed)")
|
SECTION("n (previously overflowed)")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_100000_opening_arrays.json",
|
||||||
{
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_array_object.json" })
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_100000_opening_arrays.json",
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_array_object.json"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -1231,9 +1174,7 @@ TEST_CASE("nst's JSONTestSuite (2)")
|
|||||||
|
|
||||||
SECTION("i -> y")
|
SECTION("i -> y")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : { TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_double_huge_neg_exp.json",
|
||||||
{
|
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_double_huge_neg_exp.json",
|
|
||||||
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_huge_exp.json",
|
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_huge_exp.json",
|
||||||
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_neg_int_huge_exp.json",
|
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_neg_int_huge_exp.json",
|
||||||
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_pos_double_huge_exp.json",
|
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_pos_double_huge_exp.json",
|
||||||
@@ -1267,9 +1208,7 @@ TEST_CASE("nst's JSONTestSuite (2)")
|
|||||||
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_string_utf16BE_no_BOM.json",
|
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_string_utf16BE_no_BOM.json",
|
||||||
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_string_utf16LE_no_BOM.json",
|
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_string_utf16LE_no_BOM.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_structure_UTF-8_BOM_empty_object.json"
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_structure_UTF-8_BOM_empty_object.json" })
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
@@ -1282,8 +1221,7 @@ TEST_CASE("nst's JSONTestSuite (2)")
|
|||||||
|
|
||||||
SECTION("i -> n")
|
SECTION("i -> n")
|
||||||
{
|
{
|
||||||
for (const auto* filename :
|
for (const auto* filename : {
|
||||||
{
|
|
||||||
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_double_huge_neg_exp.json",
|
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_double_huge_neg_exp.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_huge_exp.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_huge_exp.json",
|
||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_neg_int_huge_exp.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_number_neg_int_huge_exp.json",
|
||||||
@@ -1319,8 +1257,7 @@ TEST_CASE("nst's JSONTestSuite (2)")
|
|||||||
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_string_utf16LE_no_BOM.json",
|
TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_string_utf16LE_no_BOM.json",
|
||||||
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json",
|
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json",
|
||||||
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_structure_UTF-8_BOM_empty_object.json"
|
//TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_structure_UTF-8_BOM_empty_object.json"
|
||||||
}
|
})
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CAPTURE(filename)
|
CAPTURE(filename)
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
|
|||||||
@@ -61,9 +61,7 @@ float make_float(uint64_t f, int e)
|
|||||||
e--;
|
e--;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint64_t biased_exponent = (e == kDenormalExponent && (f & kHiddenBit) == 0)
|
const uint64_t biased_exponent = (e == kDenormalExponent && (f & kHiddenBit) == 0) ? 0 : static_cast<uint64_t>(e + kExponentBias);
|
||||||
? 0
|
|
||||||
: static_cast<uint64_t>(e + kExponentBias);
|
|
||||||
|
|
||||||
const uint64_t bits = (f & kSignificandMask) | (biased_exponent << kPhysicalSignificandSize);
|
const uint64_t bits = (f & kSignificandMask) | (biased_exponent << kPhysicalSignificandSize);
|
||||||
return reinterpret_bits<float>(static_cast<uint32_t>(bits));
|
return reinterpret_bits<float>(static_cast<uint32_t>(bits));
|
||||||
@@ -113,9 +111,7 @@ double make_double(uint64_t f, int e)
|
|||||||
e--;
|
e--;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint64_t biased_exponent = (e == kDenormalExponent && (f & kHiddenBit) == 0)
|
const uint64_t biased_exponent = (e == kDenormalExponent && (f & kHiddenBit) == 0) ? 0 : static_cast<uint64_t>(e + kExponentBias);
|
||||||
? 0
|
|
||||||
: static_cast<uint64_t>(e + kExponentBias);
|
|
||||||
|
|
||||||
const uint64_t bits = (f & kSignificandMask) | (biased_exponent << kPhysicalSignificandSize);
|
const uint64_t bits = (f & kSignificandMask) | (biased_exponent << kPhysicalSignificandSize);
|
||||||
return reinterpret_bits<double>(bits);
|
return reinterpret_bits<double>(bits);
|
||||||
@@ -126,8 +122,7 @@ TEST_CASE("digit gen")
|
|||||||
{
|
{
|
||||||
SECTION("single precision")
|
SECTION("single precision")
|
||||||
{
|
{
|
||||||
auto check_float = [](float number, const std::string & digits, int expected_exponent)
|
auto check_float = [](float number, const std::string& digits, int expected_exponent) {
|
||||||
{
|
|
||||||
CAPTURE(number)
|
CAPTURE(number)
|
||||||
CAPTURE(digits)
|
CAPTURE(digits)
|
||||||
CAPTURE(expected_exponent)
|
CAPTURE(expected_exponent)
|
||||||
@@ -190,8 +185,7 @@ TEST_CASE("digit gen")
|
|||||||
|
|
||||||
SECTION("double precision")
|
SECTION("double precision")
|
||||||
{
|
{
|
||||||
auto check_double = [](double number, const std::string & digits, int expected_exponent)
|
auto check_double = [](double number, const std::string& digits, int expected_exponent) {
|
||||||
{
|
|
||||||
CAPTURE(number)
|
CAPTURE(number)
|
||||||
CAPTURE(digits)
|
CAPTURE(digits)
|
||||||
CAPTURE(expected_exponent)
|
CAPTURE(expected_exponent)
|
||||||
@@ -336,8 +330,7 @@ TEST_CASE("formatting")
|
|||||||
{
|
{
|
||||||
SECTION("single precision")
|
SECTION("single precision")
|
||||||
{
|
{
|
||||||
auto check_float = [](float number, const std::string & expected)
|
auto check_float = [](float number, const std::string& expected) {
|
||||||
{
|
|
||||||
std::array<char, 33> buf{};
|
std::array<char, 33> buf{};
|
||||||
char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
std::string actual(buf.data(), end);
|
std::string actual(buf.data(), end);
|
||||||
@@ -396,8 +389,7 @@ TEST_CASE("formatting")
|
|||||||
|
|
||||||
SECTION("double precision")
|
SECTION("double precision")
|
||||||
{
|
{
|
||||||
auto check_double = [](double number, const std::string & expected)
|
auto check_double = [](double number, const std::string& expected) {
|
||||||
{
|
|
||||||
std::array<char, 33> buf{};
|
std::array<char, 33> buf{};
|
||||||
char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
std::string actual(buf.data(), end);
|
std::string actual(buf.data(), end);
|
||||||
@@ -456,8 +448,7 @@ TEST_CASE("formatting")
|
|||||||
|
|
||||||
SECTION("integer")
|
SECTION("integer")
|
||||||
{
|
{
|
||||||
auto check_integer = [](std::int64_t number, const std::string & expected)
|
auto check_integer = [](std::int64_t number, const std::string& expected) {
|
||||||
{
|
|
||||||
const nlohmann::json j = number;
|
const nlohmann::json j = number;
|
||||||
CHECK(j.dump() == expected);
|
CHECK(j.dump() == expected);
|
||||||
};
|
};
|
||||||
|
|||||||
+242
-290
File diff suppressed because it is too large
Load Diff
+50
-52
@@ -35,19 +35,25 @@ enum class country
|
|||||||
struct age
|
struct age
|
||||||
{
|
{
|
||||||
int m_val;
|
int m_val;
|
||||||
age(int rhs = 0) : m_val(rhs) {}
|
age(int rhs = 0)
|
||||||
|
: m_val(rhs)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct name
|
struct name
|
||||||
{
|
{
|
||||||
std::string m_val;
|
std::string m_val;
|
||||||
name(std::string rhs = "") : m_val(std::move(rhs)) {}
|
name(std::string rhs = "")
|
||||||
|
: m_val(std::move(rhs))
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct address
|
struct address
|
||||||
{
|
{
|
||||||
std::string m_val;
|
std::string m_val;
|
||||||
address(std::string rhs = "") : m_val(std::move(rhs)) {}
|
address(std::string rhs = "")
|
||||||
|
: m_val(std::move(rhs))
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct person
|
struct person
|
||||||
@@ -56,7 +62,11 @@ struct person
|
|||||||
name m_name{};
|
name m_name{};
|
||||||
country m_country{};
|
country m_country{};
|
||||||
person() = default;
|
person() = default;
|
||||||
person(const age& a, name n, const country& c) : m_age(a), m_name(std::move(n)), m_country(c) {}
|
person(const age& a, name n, const country& c)
|
||||||
|
: m_age(a)
|
||||||
|
, m_name(std::move(n))
|
||||||
|
, m_country(c)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct contact
|
struct contact
|
||||||
@@ -64,7 +74,10 @@ struct contact
|
|||||||
person m_person{};
|
person m_person{};
|
||||||
address m_address{};
|
address m_address{};
|
||||||
contact() = default;
|
contact() = default;
|
||||||
contact(person p, address a) : m_person(std::move(p)), m_address(std::move(a)) {}
|
contact(person p, address a)
|
||||||
|
: m_person(std::move(p))
|
||||||
|
, m_address(std::move(a))
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct contact_book
|
struct contact_book
|
||||||
@@ -72,7 +85,10 @@ struct contact_book
|
|||||||
name m_book_name{};
|
name m_book_name{};
|
||||||
std::vector<contact> m_contacts{};
|
std::vector<contact> m_contacts{};
|
||||||
contact_book() = default;
|
contact_book() = default;
|
||||||
contact_book(name n, std::vector<contact> c) : m_book_name(std::move(n)), m_contacts(std::move(c)) {}
|
contact_book(name n, std::vector<contact> c)
|
||||||
|
: m_book_name(std::move(n))
|
||||||
|
, m_contacts(std::move(c))
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
} // namespace udt
|
} // namespace udt
|
||||||
|
|
||||||
@@ -155,14 +171,12 @@ static bool operator==(const person& lhs, const person& rhs)
|
|||||||
|
|
||||||
static bool operator==(const contact& lhs, const contact& rhs)
|
static bool operator==(const contact& lhs, const contact& rhs)
|
||||||
{
|
{
|
||||||
return std::tie(lhs.m_person, lhs.m_address) ==
|
return std::tie(lhs.m_person, lhs.m_address) == std::tie(rhs.m_person, rhs.m_address);
|
||||||
std::tie(rhs.m_person, rhs.m_address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool operator==(const contact_book& lhs, const contact_book& rhs)
|
static bool operator==(const contact_book& lhs, const contact_book& rhs)
|
||||||
{
|
{
|
||||||
return std::tie(lhs.m_book_name, lhs.m_contacts) ==
|
return std::tie(lhs.m_book_name, lhs.m_contacts) == std::tie(rhs.m_book_name, rhs.m_contacts);
|
||||||
std::tie(rhs.m_book_name, rhs.m_contacts);
|
|
||||||
}
|
}
|
||||||
} // namespace udt
|
} // namespace udt
|
||||||
|
|
||||||
@@ -185,12 +199,9 @@ template <typename BasicJsonType>
|
|||||||
static void from_json(const BasicJsonType& j, country& c)
|
static void from_json(const BasicJsonType& j, country& c)
|
||||||
{
|
{
|
||||||
const auto str = j.template get<std::string>();
|
const auto str = j.template get<std::string>();
|
||||||
const std::map<std::string, country> m =
|
const std::map<std::string, country> m = { { "中华人民共和国", country::china },
|
||||||
{
|
|
||||||
{"中华人民共和国", country::china},
|
|
||||||
{ "France", country::france },
|
{ "France", country::france },
|
||||||
{"Российская Федерация", country::russia}
|
{ "Российская Федерация", country::russia } };
|
||||||
};
|
|
||||||
|
|
||||||
const auto it = m.find(str);
|
const auto it = m.find(str);
|
||||||
// TODO(nlohmann) test exceptions
|
// TODO(nlohmann) test exceptions
|
||||||
@@ -225,12 +236,8 @@ static void from_json(const nlohmann::json& j, contact_book& cb)
|
|||||||
|
|
||||||
TEST_CASE("basic usage" * doctest::test_suite("udt"))
|
TEST_CASE("basic usage" * doctest::test_suite("udt"))
|
||||||
{
|
{
|
||||||
|
|
||||||
// a bit narcissistic maybe :) ?
|
// a bit narcissistic maybe :) ?
|
||||||
const udt::age a
|
const udt::age a{ 23 };
|
||||||
{
|
|
||||||
23
|
|
||||||
};
|
|
||||||
const udt::name n{ "theo" };
|
const udt::name n{ "theo" };
|
||||||
const udt::country c{ udt::country::france };
|
const udt::country c{ udt::country::france };
|
||||||
const udt::person sfinae_addict{ a, n, c };
|
const udt::person sfinae_addict{ a, n, c };
|
||||||
@@ -246,13 +253,11 @@ TEST_CASE("basic usage" * doctest::test_suite("udt"))
|
|||||||
CHECK(json(c) == json("France"));
|
CHECK(json(c) == json("France"));
|
||||||
CHECK(json(sfinae_addict) == R"({"name":"theo", "age":23, "country":"France"})"_json);
|
CHECK(json(sfinae_addict) == R"({"name":"theo", "age":23, "country":"France"})"_json);
|
||||||
CHECK(json("Paris") == json(addr));
|
CHECK(json("Paris") == json(addr));
|
||||||
CHECK(json(cpp_programmer) ==
|
CHECK(json(cpp_programmer) == R"({"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"})"_json);
|
||||||
R"({"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"})"_json);
|
|
||||||
|
|
||||||
CHECK(
|
CHECK(
|
||||||
json(book) ==
|
json(book) ==
|
||||||
R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json);
|
R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("conversion from json via free-functions")
|
SECTION("conversion from json via free-functions")
|
||||||
@@ -263,15 +268,13 @@ TEST_CASE("basic usage" * doctest::test_suite("udt"))
|
|||||||
{
|
{
|
||||||
const auto parsed_book = big_json.get<udt::contact_book>();
|
const auto parsed_book = big_json.get<udt::contact_book>();
|
||||||
const auto book_name = big_json["name"].get<udt::name>();
|
const auto book_name = big_json["name"].get<udt::name>();
|
||||||
const auto contacts =
|
const auto contacts = big_json["contacts"].get<std::vector<udt::contact>>();
|
||||||
big_json["contacts"].get<std::vector<udt::contact>>();
|
|
||||||
const auto contact_json = big_json["contacts"].at(0);
|
const auto contact_json = big_json["contacts"].at(0);
|
||||||
const auto contact = contact_json.get<udt::contact>();
|
const auto contact = contact_json.get<udt::contact>();
|
||||||
const auto person = contact_json["person"].get<udt::person>();
|
const auto person = contact_json["person"].get<udt::person>();
|
||||||
const auto address = contact_json["address"].get<udt::address>();
|
const auto address = contact_json["address"].get<udt::address>();
|
||||||
const auto age = contact_json["person"]["age"].get<udt::age>();
|
const auto age = contact_json["person"]["age"].get<udt::age>();
|
||||||
const auto country =
|
const auto country = contact_json["person"]["country"].get<udt::country>();
|
||||||
contact_json["person"]["country"].get<udt::country>();
|
|
||||||
const auto name = contact_json["person"]["name"].get<udt::name>();
|
const auto name = contact_json["person"]["name"].get<udt::name>();
|
||||||
|
|
||||||
CHECK(age == a);
|
CHECK(age == a);
|
||||||
@@ -332,7 +335,9 @@ struct legacy_type
|
|||||||
{
|
{
|
||||||
std::string number{};
|
std::string number{};
|
||||||
legacy_type() = default;
|
legacy_type() = default;
|
||||||
legacy_type(std::string n) : number(std::move(n)) {}
|
legacy_type(std::string n)
|
||||||
|
: number(std::move(n))
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
} // namespace udt
|
} // namespace udt
|
||||||
|
|
||||||
@@ -534,10 +539,7 @@ template <typename T, typename = void>
|
|||||||
struct pod_serializer
|
struct pod_serializer
|
||||||
{
|
{
|
||||||
// use adl for non-pods, or scalar types
|
// use adl for non-pods, or scalar types
|
||||||
template <
|
template<typename BasicJsonType, typename U = T, typename std::enable_if<!(std::is_pod<U>::value && std::is_class<U>::value), int>::type = 0>
|
||||||
typename BasicJsonType, typename U = T,
|
|
||||||
typename std::enable_if <
|
|
||||||
!(std::is_pod<U>::value && std::is_class<U>::value), int >::type = 0 >
|
|
||||||
static void from_json(const BasicJsonType& j, U& t)
|
static void from_json(const BasicJsonType& j, U& t)
|
||||||
{
|
{
|
||||||
using nlohmann::from_json;
|
using nlohmann::from_json;
|
||||||
@@ -545,9 +547,7 @@ struct pod_serializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// special behaviour for pods
|
// special behaviour for pods
|
||||||
template < typename BasicJsonType, typename U = T,
|
template<typename BasicJsonType, typename U = T, typename std::enable_if<std::is_pod<U>::value && std::is_class<U>::value, int>::type = 0>
|
||||||
typename std::enable_if <
|
|
||||||
std::is_pod<U>::value && std::is_class<U>::value, int >::type = 0 >
|
|
||||||
static void from_json(const BasicJsonType& j, U& t)
|
static void from_json(const BasicJsonType& j, U& t)
|
||||||
{
|
{
|
||||||
std::uint64_t value = 0;
|
std::uint64_t value = 0;
|
||||||
@@ -570,19 +570,14 @@ struct pod_serializer
|
|||||||
std::memcpy(&t, bytes, sizeof(value));
|
std::memcpy(&t, bytes, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template<typename BasicJsonType, typename U = T, typename std::enable_if<!(std::is_pod<U>::value && std::is_class<U>::value), int>::type = 0>
|
||||||
typename BasicJsonType, typename U = T,
|
|
||||||
typename std::enable_if <
|
|
||||||
!(std::is_pod<U>::value && std::is_class<U>::value), int >::type = 0 >
|
|
||||||
static void to_json(BasicJsonType& j, const T& t)
|
static void to_json(BasicJsonType& j, const T& t)
|
||||||
{
|
{
|
||||||
using nlohmann::to_json;
|
using nlohmann::to_json;
|
||||||
to_json(j, t);
|
to_json(j, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename U = T,
|
template<typename BasicJsonType, typename U = T, typename std::enable_if<std::is_pod<U>::value && std::is_class<U>::value, int>::type = 0>
|
||||||
typename std::enable_if <
|
|
||||||
std::is_pod<U>::value && std::is_class<U>::value, int >::type = 0 >
|
|
||||||
static void to_json(BasicJsonType& j, const T& t) noexcept
|
static void to_json(BasicJsonType& j, const T& t) noexcept
|
||||||
{
|
{
|
||||||
const auto* bytes = static_cast<const unsigned char*>(static_cast<const void*>(&t)); // NOLINT(bugprone-casting-through-void)
|
const auto* bytes = static_cast<const unsigned char*>(static_cast<const void*>(&t)); // NOLINT(bugprone-casting-through-void)
|
||||||
@@ -605,7 +600,9 @@ struct non_pod
|
|||||||
{
|
{
|
||||||
std::string s{};
|
std::string s{};
|
||||||
non_pod() = default;
|
non_pod() = default;
|
||||||
non_pod(std::string S) : s(std::move(S)) {}
|
non_pod(std::string S)
|
||||||
|
: s(std::move(S))
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
@@ -622,8 +619,7 @@ static void from_json(const BasicJsonType& j, non_pod& np)
|
|||||||
|
|
||||||
static bool operator==(small_pod lhs, small_pod rhs) noexcept
|
static bool operator==(small_pod lhs, small_pod rhs) noexcept
|
||||||
{
|
{
|
||||||
return std::tie(lhs.begin, lhs.middle, lhs.end) ==
|
return std::tie(lhs.begin, lhs.middle, lhs.end) == std::tie(rhs.begin, rhs.middle, rhs.end);
|
||||||
std::tie(rhs.begin, rhs.middle, rhs.end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool operator==(const non_pod& lhs, const non_pod& rhs) noexcept
|
static bool operator==(const non_pod& lhs, const non_pod& rhs) noexcept
|
||||||
@@ -639,9 +635,7 @@ static std::ostream& operator<<(std::ostream& os, small_pod l)
|
|||||||
|
|
||||||
TEST_CASE("custom serializer for pods" * doctest::test_suite("udt"))
|
TEST_CASE("custom serializer for pods" * doctest::test_suite("udt"))
|
||||||
{
|
{
|
||||||
using custom_json =
|
using custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, pod_serializer>;
|
||||||
nlohmann::basic_json<std::map, std::vector, std::string, bool,
|
|
||||||
std::int64_t, std::uint64_t, double, std::allocator, pod_serializer>;
|
|
||||||
|
|
||||||
auto p = udt::small_pod{ 42, '/', 42 };
|
auto p = udt::small_pod{ 42, '/', 42 };
|
||||||
custom_json const j = p;
|
custom_json const j = p;
|
||||||
@@ -783,10 +777,12 @@ struct incomplete;
|
|||||||
// use the cppreference implementation
|
// use the cppreference implementation
|
||||||
|
|
||||||
template<typename T, typename = void>
|
template<typename T, typename = void>
|
||||||
struct is_constructible_patched : std::false_type {};
|
struct is_constructible_patched : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_constructible_patched<T, decltype(void(json(std::declval<T>())))> : std::true_type {};
|
struct is_constructible_patched<T, decltype(void(json(std::declval<T>())))> : std::true_type
|
||||||
|
{};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST_CASE("an incomplete type does not trigger a compiler error in non-evaluated context" * doctest::test_suite("udt"))
|
TEST_CASE("an incomplete type does not trigger a compiler error in non-evaluated context" * doctest::test_suite("udt"))
|
||||||
@@ -801,7 +797,8 @@ class Evil
|
|||||||
public:
|
public:
|
||||||
Evil() = default;
|
Evil() = default;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Evil(T t) : m_i(sizeof(t))
|
Evil(T t)
|
||||||
|
: m_i(sizeof(t))
|
||||||
{
|
{
|
||||||
static_cast<void>(t); // fix MSVC's C4100 warning
|
static_cast<void>(t); // fix MSVC's C4100 warning
|
||||||
}
|
}
|
||||||
@@ -827,7 +824,8 @@ TEST_CASE("Issue #924")
|
|||||||
|
|
||||||
TEST_CASE("Issue #1237")
|
TEST_CASE("Issue #1237")
|
||||||
{
|
{
|
||||||
struct non_convertible_type {};
|
struct non_convertible_type
|
||||||
|
{};
|
||||||
static_assert(!std::is_convertible<json, non_convertible_type>::value, "");
|
static_assert(!std::is_convertible<json, non_convertible_type>::value, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
|
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include "doctest_compatibility.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "doctest_compatibility.h"
|
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
@@ -158,32 +158,9 @@ class person_with_private_alphabet
|
|||||||
public:
|
public:
|
||||||
bool operator==(const person_with_private_alphabet& other) const
|
bool operator==(const person_with_private_alphabet& other) const
|
||||||
{
|
{
|
||||||
return a == other.a &&
|
return a == other.a && b == other.b && c == other.c && d == other.d && e == other.e && f == other.f && g == other.g && h == other.h && i == other.i &&
|
||||||
b == other.b &&
|
j == other.j && k == other.k && l == other.l && m == other.m && n == other.n && o == other.o && p == other.p && q == other.q && r == other.r &&
|
||||||
c == other.c &&
|
s == other.s && t == other.t && u == other.u && v == other.v && w == other.w && x == other.x && y == other.y && z == other.z;
|
||||||
d == other.d &&
|
|
||||||
e == other.e &&
|
|
||||||
f == other.f &&
|
|
||||||
g == other.g &&
|
|
||||||
h == other.h &&
|
|
||||||
i == other.i &&
|
|
||||||
j == other.j &&
|
|
||||||
k == other.k &&
|
|
||||||
l == other.l &&
|
|
||||||
m == other.m &&
|
|
||||||
n == other.n &&
|
|
||||||
o == other.o &&
|
|
||||||
p == other.p &&
|
|
||||||
q == other.q &&
|
|
||||||
r == other.r &&
|
|
||||||
s == other.s &&
|
|
||||||
t == other.t &&
|
|
||||||
u == other.u &&
|
|
||||||
v == other.v &&
|
|
||||||
w == other.w &&
|
|
||||||
x == other.x &&
|
|
||||||
y == other.y &&
|
|
||||||
z == other.z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -221,32 +198,9 @@ class person_with_public_alphabet
|
|||||||
public:
|
public:
|
||||||
bool operator==(const person_with_public_alphabet& other) const
|
bool operator==(const person_with_public_alphabet& other) const
|
||||||
{
|
{
|
||||||
return a == other.a &&
|
return a == other.a && b == other.b && c == other.c && d == other.d && e == other.e && f == other.f && g == other.g && h == other.h && i == other.i &&
|
||||||
b == other.b &&
|
j == other.j && k == other.k && l == other.l && m == other.m && n == other.n && o == other.o && p == other.p && q == other.q && r == other.r &&
|
||||||
c == other.c &&
|
s == other.s && t == other.t && u == other.u && v == other.v && w == other.w && x == other.x && y == other.y && z == other.z;
|
||||||
d == other.d &&
|
|
||||||
e == other.e &&
|
|
||||||
f == other.f &&
|
|
||||||
g == other.g &&
|
|
||||||
h == other.h &&
|
|
||||||
i == other.i &&
|
|
||||||
j == other.j &&
|
|
||||||
k == other.k &&
|
|
||||||
l == other.l &&
|
|
||||||
m == other.m &&
|
|
||||||
n == other.n &&
|
|
||||||
o == other.o &&
|
|
||||||
p == other.p &&
|
|
||||||
q == other.q &&
|
|
||||||
r == other.r &&
|
|
||||||
s == other.s &&
|
|
||||||
t == other.t &&
|
|
||||||
u == other.u &&
|
|
||||||
v == other.v &&
|
|
||||||
w == other.w &&
|
|
||||||
x == other.x &&
|
|
||||||
y == other.y &&
|
|
||||||
z == other.z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int a = 0;
|
int a = 0;
|
||||||
@@ -319,7 +273,8 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(person_without_default_constru
|
|||||||
|
|
||||||
} // namespace persons
|
} // namespace persons
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
|
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE",
|
||||||
|
T,
|
||||||
persons::person_with_private_data,
|
persons::person_with_private_data,
|
||||||
persons::person_without_private_data_1,
|
persons::person_without_private_data_1,
|
||||||
persons::person_without_private_data_2)
|
persons::person_without_private_data_2)
|
||||||
@@ -345,7 +300,8 @@ TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT", T,
|
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT",
|
||||||
|
T,
|
||||||
persons::person_with_private_data_2,
|
persons::person_with_private_data_2,
|
||||||
persons::person_without_private_data_3)
|
persons::person_without_private_data_3)
|
||||||
{
|
{
|
||||||
@@ -379,7 +335,9 @@ TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/private member variables via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
|
TEST_CASE_TEMPLATE(
|
||||||
|
"Serialization/deserialization of classes with 26 public/private member variables via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE",
|
||||||
|
T,
|
||||||
persons::person_with_private_alphabet,
|
persons::person_with_private_alphabet,
|
||||||
persons::person_with_public_alphabet)
|
persons::person_with_public_alphabet)
|
||||||
{
|
{
|
||||||
@@ -451,7 +409,9 @@ TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/priv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE("Serialization of non-default-constructible classes via NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE", T,
|
TEST_CASE_TEMPLATE(
|
||||||
|
"Serialization of non-default-constructible classes via NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE",
|
||||||
|
T,
|
||||||
persons::person_without_default_constructor_1,
|
persons::person_without_default_constructor_1,
|
||||||
persons::person_without_default_constructor_2)
|
persons::person_without_default_constructor_2)
|
||||||
{
|
{
|
||||||
@@ -463,11 +423,7 @@ TEST_CASE_TEMPLATE("Serialization of non-default-constructible classes via NLOHM
|
|||||||
CHECK(json(person).dump() == "{\"age\":1,\"name\":\"Erik\"}");
|
CHECK(json(person).dump() == "{\"age\":1,\"name\":\"Erik\"}");
|
||||||
|
|
||||||
// serialization of a container with objects
|
// serialization of a container with objects
|
||||||
std::vector<T> const two_persons
|
std::vector<T> const two_persons{ { "Erik", 1 }, { "Kyle", 2 } };
|
||||||
{
|
|
||||||
{"Erik", 1},
|
|
||||||
{"Kyle", 2}
|
|
||||||
};
|
|
||||||
CHECK(json(two_persons).dump() == "[{\"age\":1,\"name\":\"Erik\"},{\"age\":2,\"name\":\"Kyle\"}]");
|
CHECK(json(two_persons).dump() == "[{\"age\":1,\"name\":\"Erik\"},{\"age\":2,\"name\":\"Kyle\"}]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-14
@@ -13,18 +13,17 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
TEST_CASE("Unicode (1/5)" * doctest::skip())
|
TEST_CASE("Unicode (1/5)" * doctest::skip())
|
||||||
{
|
{
|
||||||
SECTION("\\uxxxx sequences")
|
SECTION("\\uxxxx sequences")
|
||||||
{
|
{
|
||||||
// create an escaped string from a code point
|
// create an escaped string from a code point
|
||||||
const auto codepoint_to_unicode = [](std::size_t cp)
|
const auto codepoint_to_unicode = [](std::size_t cp) {
|
||||||
{
|
|
||||||
// code points are represented as a six-character sequence: a
|
// code points are represented as a six-character sequence: a
|
||||||
// reverse solidus, followed by the lowercase letter u, followed
|
// reverse solidus, followed by the lowercase letter u, followed
|
||||||
// by four hexadecimal digits that encode the character's code
|
// by four hexadecimal digits that encode the character's code
|
||||||
@@ -86,19 +85,40 @@ TEST_CASE("Unicode (1/5)" * doctest::skip())
|
|||||||
{
|
{
|
||||||
json _;
|
json _;
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\uDC00\\uDC00\""), "[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '\"\\uDC00'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse("\"\\uDC00\\uDC00\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 7: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '\"\\uDC00'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\uD7FF\\uDC00\""), "[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '\"\\uD7FF\\uDC00'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse("\"\\uD7FF\\uDC00\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '\"\\uD7FF\\uDC00'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\uD800]\""), "[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD800]'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse("\"\\uD800]\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD800]'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\uD800\\v\""), "[json.exception.parse_error.101] parse error at line 1, column 9: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD800\\v'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse("\"\\uD800\\v\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 9: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD800\\v'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\uD800\\u123\""), "[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\uD800\\u123\"'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse("\"\\uD800\\u123\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\uD800\\u123\"'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\uD800\\uDBFF\""), "[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD800\\uDBFF'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse("\"\\uD800\\uDBFF\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD800\\uDBFF'",
|
||||||
|
json::parse_error&);
|
||||||
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\uD800\\uE000\""), "[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD800\\uE000'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(
|
||||||
|
_ = json::parse("\"\\uD800\\uE000\""),
|
||||||
|
"[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD800\\uE000'",
|
||||||
|
json::parse_error&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,13 +375,17 @@ TEST_CASE("Markus Kuhn's UTF-8 decoder capability and stress test")
|
|||||||
roundtrip(false, "\x80\xbf\x80\xbf\x80\xbf\x80");
|
roundtrip(false, "\x80\xbf\x80\xbf\x80\xbf\x80");
|
||||||
|
|
||||||
// 3.1.9 Sequence of all 64 possible continuation bytes (0x80-0xbf)
|
// 3.1.9 Sequence of all 64 possible continuation bytes (0x80-0xbf)
|
||||||
roundtrip(false, "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf");
|
roundtrip(
|
||||||
|
false,
|
||||||
|
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("3.2 Lonely start characters")
|
SECTION("3.2 Lonely start characters")
|
||||||
{
|
{
|
||||||
// 3.2.1 All 32 first bytes of 2-byte sequences (0xc0-0xdf)
|
// 3.2.1 All 32 first bytes of 2-byte sequences (0xc0-0xdf)
|
||||||
roundtrip(false, "\xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf");
|
roundtrip(
|
||||||
|
false,
|
||||||
|
"\xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf");
|
||||||
// 3.2.2 All 16 first bytes of 3-byte sequences (0xe0-0xef)
|
// 3.2.2 All 16 first bytes of 3-byte sequences (0xe0-0xef)
|
||||||
roundtrip(false, "\xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef");
|
roundtrip(false, "\xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef");
|
||||||
// 3.2.3 All 8 first bytes of 4-byte sequences (0xf0-0xf7)
|
// 3.2.3 All 8 first bytes of 4-byte sequences (0xf0-0xf7)
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
// this test suite uses static variables with non-trivial destructors
|
// this test suite uses static variables with non-trivial destructors
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
// this test suite uses static variables with non-trivial destructors
|
// this test suite uses static variables with non-trivial destructors
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
// this test suite uses static variables with non-trivial destructors
|
// this test suite uses static variables with non-trivial destructors
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
// this test suite uses static variables with non-trivial destructors
|
// this test suite uses static variables with non-trivial destructors
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||||
|
|||||||
@@ -44,14 +44,12 @@ const char* end(const MyContainer& c)
|
|||||||
|
|
||||||
TEST_CASE("Custom container non-member begin/end")
|
TEST_CASE("Custom container non-member begin/end")
|
||||||
{
|
{
|
||||||
|
|
||||||
const MyContainer data{ "[1,2,3,4]" };
|
const MyContainer data{ "[1,2,3,4]" };
|
||||||
json as_json = json::parse(data);
|
json as_json = json::parse(data);
|
||||||
CHECK(as_json.at(0) == 1);
|
CHECK(as_json.at(0) == 1);
|
||||||
CHECK(as_json.at(1) == 2);
|
CHECK(as_json.at(1) == 2);
|
||||||
CHECK(as_json.at(2) == 3);
|
CHECK(as_json.at(2) == 3);
|
||||||
CHECK(as_json.at(3) == 4);
|
CHECK(as_json.at(3) == 4);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Custom container member begin/end")
|
TEST_CASE("Custom container member begin/end")
|
||||||
|
|||||||
Reference in New Issue
Block a user