From a7c4c84d683735339abd221739577dbdbf64d35b Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 22 Jul 2020 12:03:37 +0200 Subject: [PATCH 01/17] :white_check_mark: add regression test for #2281 --- .../cmake_target_include_directories/project/Bar.cpp | 3 +++ .../cmake_target_include_directories/project/Bar.hpp | 4 ++++ .../project/CMakeLists.txt | 12 ++++++++++++ .../cmake_target_include_directories/project/Foo.cpp | 3 +++ .../cmake_target_include_directories/project/Foo.hpp | 4 ++++ 5 files changed, 26 insertions(+) create mode 100644 test/cmake_target_include_directories/project/Bar.cpp create mode 100644 test/cmake_target_include_directories/project/Bar.hpp create mode 100644 test/cmake_target_include_directories/project/Foo.cpp create mode 100644 test/cmake_target_include_directories/project/Foo.hpp diff --git a/test/cmake_target_include_directories/project/Bar.cpp b/test/cmake_target_include_directories/project/Bar.cpp new file mode 100644 index 00000000..ed39e284 --- /dev/null +++ b/test/cmake_target_include_directories/project/Bar.cpp @@ -0,0 +1,3 @@ +#include "Bar.hpp" + +class Bar; diff --git a/test/cmake_target_include_directories/project/Bar.hpp b/test/cmake_target_include_directories/project/Bar.hpp new file mode 100644 index 00000000..bdb1d9b5 --- /dev/null +++ b/test/cmake_target_include_directories/project/Bar.hpp @@ -0,0 +1,4 @@ +#include +#include "Foo.hpp" + +class Bar : public Foo{}; diff --git a/test/cmake_target_include_directories/project/CMakeLists.txt b/test/cmake_target_include_directories/project/CMakeLists.txt index 20e971a0..36f3da0c 100644 --- a/test/cmake_target_include_directories/project/CMakeLists.txt +++ b/test/cmake_target_include_directories/project/CMakeLists.txt @@ -9,3 +9,15 @@ set_target_properties(with_private_target PROPERTIES CXX_STANDARD 11) add_executable(with_private_system_target main.cpp) target_include_directories(with_private_system_target PRIVATE SYSTEM ${nlohmann_json_source}/include) set_target_properties(with_private_system_target PROPERTIES CXX_STANDARD 11) + +# regression from https://github.com/nlohmann/json/discussions/2281 +add_library(Foo SHARED) +target_sources(Foo PRIVATE Foo.cpp Bar.cpp) +target_include_directories(Foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include) +set_target_properties(Foo PROPERTIES CXX_STANDARD 11) + +add_library(Bar SHARED) +target_sources(Bar PRIVATE Bar.cpp) +target_link_libraries(Bar PRIVATE Foo) +target_include_directories(Bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include) +set_target_properties(Bar PROPERTIES CXX_STANDARD 11) diff --git a/test/cmake_target_include_directories/project/Foo.cpp b/test/cmake_target_include_directories/project/Foo.cpp new file mode 100644 index 00000000..6a2ff91a --- /dev/null +++ b/test/cmake_target_include_directories/project/Foo.cpp @@ -0,0 +1,3 @@ +#include "Foo.hpp" + +class Foo; diff --git a/test/cmake_target_include_directories/project/Foo.hpp b/test/cmake_target_include_directories/project/Foo.hpp new file mode 100644 index 00000000..fd6b1ffa --- /dev/null +++ b/test/cmake_target_include_directories/project/Foo.hpp @@ -0,0 +1,4 @@ +#pragma once +#include + +class Foo{}; From 4d63252c6cec0eb3fa1db1564cfc213386ed3929 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 22 Jul 2020 12:23:58 +0200 Subject: [PATCH 02/17] :white_check_mark: add regression test for #2281 --- test/cmake_target_include_directories/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cmake_target_include_directories/CMakeLists.txt b/test/cmake_target_include_directories/CMakeLists.txt index da738ea4..d0f3335f 100644 --- a/test/cmake_target_include_directories/CMakeLists.txt +++ b/test/cmake_target_include_directories/CMakeLists.txt @@ -2,6 +2,7 @@ add_test(NAME cmake_target_include_directories_configure COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_BUILD_TYPE=Debug -Dnlohmann_json_source=${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/project ) From c4356c68e07eba22e5fdd53bd036ee3332b5e87e Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 22 Jul 2020 12:38:39 +0200 Subject: [PATCH 03/17] :white_check_mark: add regression test for #2281 --- test/cmake_target_include_directories/CMakeLists.txt | 1 - .../cmake_target_include_directories/project/CMakeLists.txt | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/test/cmake_target_include_directories/CMakeLists.txt b/test/cmake_target_include_directories/CMakeLists.txt index d0f3335f..da738ea4 100644 --- a/test/cmake_target_include_directories/CMakeLists.txt +++ b/test/cmake_target_include_directories/CMakeLists.txt @@ -2,7 +2,6 @@ add_test(NAME cmake_target_include_directories_configure COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_BUILD_TYPE=Debug -Dnlohmann_json_source=${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/project ) diff --git a/test/cmake_target_include_directories/project/CMakeLists.txt b/test/cmake_target_include_directories/project/CMakeLists.txt index 36f3da0c..a5e0919d 100644 --- a/test/cmake_target_include_directories/project/CMakeLists.txt +++ b/test/cmake_target_include_directories/project/CMakeLists.txt @@ -11,13 +11,11 @@ target_include_directories(with_private_system_target PRIVATE SYSTEM ${nlohmann_ set_target_properties(with_private_system_target PROPERTIES CXX_STANDARD 11) # regression from https://github.com/nlohmann/json/discussions/2281 -add_library(Foo SHARED) -target_sources(Foo PRIVATE Foo.cpp Bar.cpp) +add_library(Foo SHARED Foo.cpp Bar.cpp) target_include_directories(Foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include) set_target_properties(Foo PROPERTIES CXX_STANDARD 11) -add_library(Bar SHARED) -target_sources(Bar PRIVATE Bar.cpp) +add_library(Bar SHARED PRIVATE Bar.cpp) target_link_libraries(Bar PRIVATE Foo) target_include_directories(Bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include) set_target_properties(Bar PROPERTIES CXX_STANDARD 11) From 2301bd1177a9666f1fb5f7bdf407055df88c2bf4 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 22 Jul 2020 13:24:07 +0200 Subject: [PATCH 04/17] :white_check_mark: add regression test for #2281 --- test/cmake_target_include_directories/project/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cmake_target_include_directories/project/CMakeLists.txt b/test/cmake_target_include_directories/project/CMakeLists.txt index a5e0919d..0f997695 100644 --- a/test/cmake_target_include_directories/project/CMakeLists.txt +++ b/test/cmake_target_include_directories/project/CMakeLists.txt @@ -15,7 +15,7 @@ add_library(Foo SHARED Foo.cpp Bar.cpp) target_include_directories(Foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include) set_target_properties(Foo PROPERTIES CXX_STANDARD 11) -add_library(Bar SHARED PRIVATE Bar.cpp) +add_library(Bar SHARED Bar.cpp) target_link_libraries(Bar PRIVATE Foo) target_include_directories(Bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include) set_target_properties(Bar PROPERTIES CXX_STANDARD 11) From a6d112ffbf0005cf1a7d61236523bcae89be4ae0 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 22 Jul 2020 13:39:40 +0200 Subject: [PATCH 05/17] :white_check_mark: add regression test for #2281 --- test/cmake_target_include_directories/project/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cmake_target_include_directories/project/CMakeLists.txt b/test/cmake_target_include_directories/project/CMakeLists.txt index 0f997695..f56786c0 100644 --- a/test/cmake_target_include_directories/project/CMakeLists.txt +++ b/test/cmake_target_include_directories/project/CMakeLists.txt @@ -11,11 +11,11 @@ target_include_directories(with_private_system_target PRIVATE SYSTEM ${nlohmann_ set_target_properties(with_private_system_target PROPERTIES CXX_STANDARD 11) # regression from https://github.com/nlohmann/json/discussions/2281 -add_library(Foo SHARED Foo.cpp Bar.cpp) +add_library(Foo STATIC Foo.cpp Bar.cpp) target_include_directories(Foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include) set_target_properties(Foo PROPERTIES CXX_STANDARD 11) -add_library(Bar SHARED Bar.cpp) +add_library(Bar STATIC Bar.cpp) target_link_libraries(Bar PRIVATE Foo) target_include_directories(Bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include) set_target_properties(Bar PROPERTIES CXX_STANDARD 11) From 230dcfb7a3b1664cbd367d722885dc1c7cbb9ead Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 23 Jul 2020 12:57:52 +0200 Subject: [PATCH 06/17] :rotating_light: add prefix to avoid shadowing --- include/nlohmann/detail/macro_scope.hpp | 12 ++++++------ single_include/nlohmann/json.hpp | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/nlohmann/detail/macro_scope.hpp b/include/nlohmann/detail/macro_scope.hpp index c32a46d1..cdc8d5a4 100644 --- a/include/nlohmann/detail/macro_scope.hpp +++ b/include/nlohmann/detail/macro_scope.hpp @@ -264,8 +264,8 @@ #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) -#define NLOHMANN_JSON_TO(v1) j[#v1] = t.v1; -#define NLOHMANN_JSON_FROM(v1) j.at(#v1).get_to(t.v1); +#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; +#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); /*! @brief macro @@ -273,8 +273,8 @@ @since version 3.9.0 */ #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ - friend void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @@ -282,8 +282,8 @@ @since version 3.9.0 */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } #ifndef JSON_USE_IMPLICIT_CONVERSIONS #define JSON_USE_IMPLICIT_CONVERSIONS 1 diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 0b7d2411..6f719fc0 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -2281,8 +2281,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) -#define NLOHMANN_JSON_TO(v1) j[#v1] = t.v1; -#define NLOHMANN_JSON_FROM(v1) j.at(#v1).get_to(t.v1); +#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; +#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); /*! @brief macro @@ -2290,8 +2290,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP @since version 3.9.0 */ #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ - friend void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @@ -2299,8 +2299,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP @since version 3.9.0 */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } #ifndef JSON_USE_IMPLICIT_CONVERSIONS #define JSON_USE_IMPLICIT_CONVERSIONS 1 From 8159091d8f2d163470d2a8d69f8e95dbf75f1708 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 23 Jul 2020 12:58:09 +0200 Subject: [PATCH 07/17] :twisted_rightwards_arrows: rename variable to avoid shadowing --- test/src/unit-conversions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/src/unit-conversions.cpp b/test/src/unit-conversions.cpp index 97a4e6b6..7ab0e9a3 100644 --- a/test/src/unit-conversions.cpp +++ b/test/src/unit-conversions.cpp @@ -278,8 +278,8 @@ TEST_CASE("value conversion") SECTION("reserve is called on containers that supports it") { // make sure all values are properly copied - json j({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); - auto v2 = j.get>(); + json j2({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); + auto v2 = j2.get>(); CHECK(v2.size() == 10); } #endif From f9b71afebf853481ade545056f25fc6f393ec24c Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 23 Jul 2020 13:02:53 +0200 Subject: [PATCH 08/17] :truck: unify cmake build dir names --- Makefile | 76 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/Makefile b/Makefile index fd73a338..89350650 100644 --- a/Makefile +++ b/Makefile @@ -54,13 +54,13 @@ all: ########################################################################## coverage: - rm -fr build_coverage - mkdir build_coverage - cd build_coverage ; cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_Coverage=ON -DJSON_MultipleHeaders=ON - cd build_coverage ; ninja - cd build_coverage ; ctest -j10 - cd build_coverage ; ninja lcov_html - open build_coverage/test/html/index.html + rm -fr cmake-build-coverage + mkdir cmake-build-coverage + cd cmake-build-coverage ; cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_Coverage=ON -DJSON_MultipleHeaders=ON + cd cmake-build-coverage ; ninja + cd cmake-build-coverage ; ctest -j10 + cd cmake-build-coverage ; ninja lcov_html + open cmake-build-coverage/test/html/index.html ########################################################################## # documentation tests @@ -88,7 +88,7 @@ doctest: # -Wno-switch-enum -Wno-covered-switch-default: pedantic/contradicting warnings about switches # -Wno-weak-vtables: exception class is defined inline, but has virtual method pedantic_clang: - rm -fr build_pedantic + rm -fr cmake-build-pedantic CXXFLAGS=" \ -std=c++11 -Wno-c++98-compat -Wno-c++98-compat-pedantic \ -Werror \ @@ -103,12 +103,12 @@ pedantic_clang: -Wno-padded \ -Wno-range-loop-analysis \ -Wno-switch-enum -Wno-covered-switch-default \ - -Wno-weak-vtables" cmake -S . -B build_pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On - cmake --build build_pedantic + -Wno-weak-vtables" cmake -S . -B cmake-build-pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On + cmake --build cmake-build-pedantic # calling GCC with most warnings pedantic_gcc: - rm -fr build_pedantic + rm -fr cmake-build-pedantic CXXFLAGS=" \ -std=c++11 \ -pedantic \ @@ -366,19 +366,19 @@ pedantic_gcc: -Wwrite-strings \ -Wzero-as-null-pointer-constant \ -Wzero-length-bounds \ - " cmake -S . -B build_pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On - cmake --build build_pedantic + " cmake -S . -B cmake-build-pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On + cmake --build cmake-build-pedantic ########################################################################## # benchmarks ########################################################################## run_benchmarks: - rm -fr build_benchmarks - mkdir build_benchmarks - cd build_benchmarks ; cmake ../benchmarks -GNinja -DCMAKE_BUILD_TYPE=Release -DJSON_BuildTests=On - cd build_benchmarks ; ninja - cd build_benchmarks ; ./json_benchmarks + rm -fr cmake-build-benchmarks + mkdir cmake-build-benchmarks + cd cmake-build-benchmarks ; cmake ../benchmarks -GNinja -DCMAKE_BUILD_TYPE=Release -DJSON_BuildTests=On + cd cmake-build-benchmarks ; ninja + cd cmake-build-benchmarks ; ./json_benchmarks ########################################################################## # fuzzing @@ -451,14 +451,14 @@ cppcheck: # call Clang Static Analyzer clang_analyze: - rm -fr clang_analyze_build - mkdir clang_analyze_build - cd clang_analyze_build ; CCC_CXX=$(COMPILER_DIR)/clang++ CXX=$(COMPILER_DIR)/clang++ $(COMPILER_DIR)/scan-build cmake .. -GNinja -DJSON_BuildTests=On - cd clang_analyze_build ; \ + rm -fr cmake-build-clang-analyze + mkdir cmake-build-clang-analyze + cd cmake-build-clang-analyze ; CCC_CXX=$(COMPILER_DIR)/clang++ CXX=$(COMPILER_DIR)/clang++ $(COMPILER_DIR)/scan-build cmake .. -GNinja -DJSON_BuildTests=On + cd cmake-build-clang-analyze ; \ $(COMPILER_DIR)/scan-build \ -enable-checker alpha.core.BoolAssignment,alpha.core.CallAndMessageUnInitRefArg,alpha.core.CastSize,alpha.core.CastToStruct,alpha.core.Conversion,alpha.core.DynamicTypeChecker,alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,alpha.core.SizeofPtr,alpha.core.StackAddressAsyncEscape,alpha.core.TestAfterDivZero,alpha.deadcode.UnreachableCode,core.builtin.BuiltinFunctions,core.builtin.NoReturnFunctions,core.CallAndMessage,core.DivideZero,core.DynamicTypePropagation,core.NonnilStringConstants,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,core.VLASize,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.SelfAssignment,deadcode.DeadStores,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull \ --use-c++=$(COMPILER_DIR)/clang++ -analyze-headers -o report ninja - open clang_analyze_build/report/*/index.html + open cmake-build-clang-analyze/report/*/index.html # call cpplint # Note: some errors expected due to false positives @@ -473,18 +473,18 @@ clang_tidy: # call PVS-Studio Analyzer pvs_studio: - rm -fr pvs_studio_build - mkdir pvs_studio_build - cd pvs_studio_build ; cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DJSON_MultipleHeaders=ON - cd pvs_studio_build ; pvs-studio-analyzer analyze -j 10 - cd pvs_studio_build ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs - open pvs_studio_build/pvs/index.html + rm -fr cmake-build-pvs-studio + mkdir cmake-build-pvs-studio + cd cmake-build-pvs-studio ; cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DJSON_MultipleHeaders=ON + cd cmake-build-pvs-studio ; pvs-studio-analyzer analyze -j 10 + cd cmake-build-pvs-studio ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs + open cmake-build-pvs-studio/pvs/index.html # call Infer static analyzer infer: - rm -fr infer_build - mkdir infer_build - cd infer_build ; infer compile -- cmake .. -DJSON_MultipleHeaders=ON ; infer run -- make -j 4 + rm -fr cmake-build-infer + mkdir cmake-build-infer + cd cmake-build-infer ; infer compile -- cmake .. -DJSON_MultipleHeaders=ON ; infer run -- make -j 4 # call OCLint static analyzer oclint: @@ -493,11 +493,11 @@ oclint: # execute the test suite with Clang sanitizers (address and undefined behavior) clang_sanitize: - rm -fr clang_sanitize_build - mkdir clang_sanitize_build - cd clang_sanitize_build ; CXX=$(COMPILER_DIR)/clang++ cmake .. -DJSON_Sanitizer=On -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On -GNinja - cd clang_sanitize_build ; ninja - cd clang_sanitize_build ; ctest -j10 + rm -fr cmake-build-clang-sanitize + mkdir cmake-build-clang-sanitize + cd cmake-build-clang-sanitize ; CXX=$(COMPILER_DIR)/clang++ cmake .. -DJSON_Sanitizer=On -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On -GNinja + cd cmake-build-clang-sanitize ; ninja + cd cmake-build-clang-sanitize ; ctest -j10 ########################################################################## @@ -625,7 +625,7 @@ clean: rm -fr json_unit json_benchmarks fuzz fuzz-testing *.dSYM test/*.dSYM oclint_report.html rm -fr benchmarks/files/numbers/*.json rm -fr cmake-3.1.0-Darwin64.tar.gz cmake-3.1.0-Darwin64 - rm -fr build_coverage build_benchmarks fuzz-testing clang_analyze_build pvs_studio_build infer_build clang_sanitize_build cmake_build + rm -fr cmake-build-coverage cmake-build-benchmarks fuzz-testing cmake-build-clang-analyze cmake-build-pvs-studio cmake-build-infer cmake-build-clang-sanitize cmake_build $(MAKE) clean -Cdoc ########################################################################## From fb22233f349c5000aa26461d1cc30d1883c9e497 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 23 Jul 2020 13:11:48 +0200 Subject: [PATCH 09/17] :loud_sound: add message if implicit conversions are switched off --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b18b83d..7ee9381d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ endif () option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ON) option(JSON_Install "Install CMake targets during install step." ON) option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF) -option(JSON_ImplicitConversions "Enable implicit conversions" ON) +option(JSON_ImplicitConversions "Enable implicit conversions." ON) ## ## CONFIGURATION @@ -49,6 +49,10 @@ else() message(STATUS "Using the single-header code from ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}") endif() +if (NOT JSON_ImplicitConversions) + message(STATUS "Implicit conversions are disabled") +endif() + ## ## TARGET ## create target and add include path From e571c67c0de803f938111f823bad7c383429f4c1 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 23 Jul 2020 14:02:12 +0200 Subject: [PATCH 10/17] :rotating_light: fix implicit conversion warning when opening binary file --- Makefile | 2 +- test/CMakeLists.txt | 2 +- test/src/unit-bson.cpp | 16 ++++------------ test/src/unit-cbor.cpp | 33 ++++++++------------------------- test/src/unit-msgpack.cpp | 20 +++++--------------- test/src/unit-ubjson.cpp | 24 ++++++++---------------- test/utils/test_utils.hpp | 25 +++++++++++++++++++++++++ 7 files changed, 52 insertions(+), 70 deletions(-) create mode 100644 test/utils/test_utils.hpp diff --git a/Makefile b/Makefile index 89350650..9d26bc9d 100644 --- a/Makefile +++ b/Makefile @@ -525,7 +525,7 @@ pretty: --preserve-date \ --suffix=none \ --formatted \ - $(SRCS) $(AMALGAMATED_FILE) test/src/*.cpp benchmarks/src/benchmarks.cpp doc/examples/*.cpp + $(SRCS) $(AMALGAMATED_FILE) test/src/*.cpp test/utils/*.hpp benchmarks/src/benchmarks.cpp doc/examples/*.cpp # create single header file amalgamate: $(AMALGAMATED_FILE) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 76ba31d8..9ce1594c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -151,7 +151,7 @@ foreach(file ${files}) $<$>:-Wno-deprecated;-Wno-float-equal> $<$:-Wno-deprecated-declarations> ) - target_include_directories(${testcase} PRIVATE ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map) + target_include_directories(${testcase} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/utils ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map) target_link_libraries(${testcase} PRIVATE ${NLOHMANN_JSON_TARGET_NAME}) if (JSON_Coverage) diff --git a/test/src/unit-bson.cpp b/test/src/unit-bson.cpp index aa3acbc3..80a8012d 100644 --- a/test/src/unit-bson.cpp +++ b/test/src/unit-bson.cpp @@ -35,6 +35,7 @@ using nlohmann::json; #include #include #include +#include TEST_CASE("BSON") { @@ -1263,10 +1264,7 @@ TEST_CASE("BSON roundtrips" * doctest::skip()) json j1 = json::parse(f_json); // parse BSON file - std::ifstream f_bson(filename + ".bson", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_bson)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(filename + ".bson"); json j2; CHECK_NOTHROW(j2 = json::from_bson(packed)); @@ -1296,10 +1294,7 @@ TEST_CASE("BSON roundtrips" * doctest::skip()) json j1 = json::parse(f_json); // parse BSON file - std::ifstream f_bson(filename + ".bson", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_bson)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(filename + ".bson"); json j2; CHECK_NOTHROW(j2 = json::from_bson({packed.data(), packed.size()})); @@ -1314,10 +1309,7 @@ TEST_CASE("BSON roundtrips" * doctest::skip()) json j1 = json::parse(f_json); // parse BSON file - std::ifstream f_bson(filename + ".bson", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_bson)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(filename + ".bson"); { INFO_WITH_TEMP(filename + ": output adapters: std::vector"); diff --git a/test/src/unit-cbor.cpp b/test/src/unit-cbor.cpp index 7eaba84a..d5641327 100644 --- a/test/src/unit-cbor.cpp +++ b/test/src/unit-cbor.cpp @@ -39,6 +39,7 @@ using nlohmann::json; #include #include #include +#include namespace { @@ -1920,9 +1921,7 @@ TEST_CASE("single CBOR roundtrip") json j1 = json::parse(f_json); // parse CBOR file - std::ifstream f_cbor(filename + ".cbor", std::ios::binary); - std::vector packed((std::istreambuf_iterator(f_cbor)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(filename + ".cbor"); json j2; CHECK_NOTHROW(j2 = json::from_cbor(packed)); @@ -1994,10 +1993,7 @@ TEST_CASE("CBOR regressions") try { // parse CBOR file - std::ifstream f_cbor(filename, std::ios::binary); - std::vector vec1( - (std::istreambuf_iterator(f_cbor)), - std::istreambuf_iterator()); + auto vec1 = utils::read_binary_file(filename); json j1 = json::from_cbor(vec1); try @@ -2204,10 +2200,7 @@ TEST_CASE("CBOR roundtrips" * doctest::skip()) json j1 = json::parse(f_json); // parse CBOR file - std::ifstream f_cbor(filename + ".cbor", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_cbor)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(filename + ".cbor"); json j2; CHECK_NOTHROW(j2 = json::from_cbor(packed)); @@ -2237,10 +2230,7 @@ TEST_CASE("CBOR roundtrips" * doctest::skip()) json j1 = json::parse(f_json); // parse CBOR file - std::ifstream f_cbor(filename + ".cbor", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_cbor)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(filename + ".cbor"); json j2; CHECK_NOTHROW(j2 = json::from_cbor({packed.data(), packed.size()})); @@ -2255,10 +2245,7 @@ TEST_CASE("CBOR roundtrips" * doctest::skip()) json j1 = json::parse(f_json); // parse CBOR file - std::ifstream f_cbor(filename + ".cbor", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_cbor)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(filename + ".cbor"); if (!exclude_packed.count(filename)) { @@ -2493,15 +2480,11 @@ TEST_CASE("examples from RFC 7049 Appendix A") SECTION("byte arrays") { - std::ifstream f_cbor(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.cbor", std::ios::binary); - std::vector packed((std::istreambuf_iterator(f_cbor)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.cbor"); json j; CHECK_NOTHROW(j = json::from_cbor(packed)); - std::ifstream f_bin(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.out", std::ios::binary); - std::vector expected((std::istreambuf_iterator(f_bin)), - std::istreambuf_iterator()); + auto expected = utils::read_binary_file(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.out"); CHECK(j == json::binary(expected)); CHECK(json::to_cbor(json::binary(std::vector {}, 0x42)) == std::vector {0xd8, 0x42, 0x40}); diff --git a/test/src/unit-msgpack.cpp b/test/src/unit-msgpack.cpp index 2130c887..9275ad5e 100644 --- a/test/src/unit-msgpack.cpp +++ b/test/src/unit-msgpack.cpp @@ -37,6 +37,7 @@ using nlohmann::json; #include #include #include +#include namespace { @@ -1609,9 +1610,7 @@ TEST_CASE("single MessagePack roundtrip") json j1 = json::parse(f_json); // parse MessagePack file - std::ifstream f_msgpack(filename + ".msgpack", std::ios::binary); - std::vector packed((std::istreambuf_iterator(f_msgpack)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(filename + ".msgpack"); json j2; CHECK_NOTHROW(j2 = json::from_msgpack(packed)); @@ -1824,10 +1823,7 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip()) json j1 = json::parse(f_json); // parse MessagePack file - std::ifstream f_msgpack(filename + ".msgpack", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_msgpack)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(filename + ".msgpack"); json j2; CHECK_NOTHROW(j2 = json::from_msgpack(packed)); @@ -1857,10 +1853,7 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip()) json j1 = json::parse(f_json); // parse MessagePack file - std::ifstream f_msgpack(filename + ".msgpack", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_msgpack)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(filename + ".msgpack"); json j2; CHECK_NOTHROW(j2 = json::from_msgpack({packed.data(), packed.size()})); @@ -1875,10 +1868,7 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip()) json j1 = json::parse(f_json); // parse MessagePack file - std::ifstream f_msgpack(filename + ".msgpack", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_msgpack)), - std::istreambuf_iterator()); + auto packed = utils::read_binary_file(filename + ".msgpack"); if (!exclude_packed.count(filename)) { diff --git a/test/src/unit-ubjson.cpp b/test/src/unit-ubjson.cpp index 0f95bcec..ac133c0b 100644 --- a/test/src/unit-ubjson.cpp +++ b/test/src/unit-ubjson.cpp @@ -35,6 +35,7 @@ using nlohmann::json; #include #include #include +#include namespace { @@ -2457,11 +2458,8 @@ TEST_CASE("UBJSON roundtrips" * doctest::skip()) std::ifstream f_json(filename); json j1 = json::parse(f_json); - // parse MessagePack file - std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_ubjson)), - std::istreambuf_iterator()); + // parse UBJSON file + auto packed = utils::read_binary_file(filename + ".ubjson"); json j2; CHECK_NOTHROW(j2 = json::from_ubjson(packed)); @@ -2475,7 +2473,7 @@ TEST_CASE("UBJSON roundtrips" * doctest::skip()) std::ifstream f_json(filename); json j1 = json::parse(f_json); - // parse MessagePack file + // parse UBJSON file std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary); json j2; CHECK_NOTHROW(j2 = json::from_ubjson(f_ubjson)); @@ -2490,11 +2488,8 @@ TEST_CASE("UBJSON roundtrips" * doctest::skip()) std::ifstream f_json(filename); json j1 = json::parse(f_json); - // parse MessagePack file - std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_ubjson)), - std::istreambuf_iterator()); + // parse UBJSON file + auto packed = utils::read_binary_file(filename + ".ubjson"); json j2; CHECK_NOTHROW(j2 = json::from_ubjson({packed.data(), packed.size()})); @@ -2508,11 +2503,8 @@ TEST_CASE("UBJSON roundtrips" * doctest::skip()) std::ifstream f_json(filename); json j1 = json::parse(f_json); - // parse MessagePack file - std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary); - std::vector packed( - (std::istreambuf_iterator(f_ubjson)), - std::istreambuf_iterator()); + // parse UBJSON file + auto packed = utils::read_binary_file(filename + ".ubjson"); { INFO_WITH_TEMP(filename + ": output adapters: std::vector"); diff --git a/test/utils/test_utils.hpp b/test/utils/test_utils.hpp new file mode 100644 index 00000000..12c260e7 --- /dev/null +++ b/test/utils/test_utils.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include // uint8_t +#include // ifstream, istreambuf_iterator, ios +#include // vector + +namespace utils +{ + +inline std::vector read_binary_file(const std::string& filename) +{ + std::ifstream file(filename, std::ios::binary); + file.unsetf(std::ios::skipws); + + file.seekg(0, std::ios::end); + const auto size = file.tellg(); + file.seekg(0, std::ios::beg); + + std::vector byte_vector; + byte_vector.reserve(static_cast(size)); + byte_vector.insert(byte_vector.begin(), std::istream_iterator(file), std::istream_iterator()); + return byte_vector; +} + +} // namespace utils From bba57cc4af7f52f2d880842e0020b1d6e2af35f5 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 23 Jul 2020 14:02:49 +0200 Subject: [PATCH 11/17] :rotating_light: fix UBSAN warning --- test/src/unit-regression.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp index 649ac656..d70114ee 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -1516,8 +1516,8 @@ TEST_CASE("regression tests") SECTION("issue #838 - incorrect parse error with binary data in keys") { - uint8_t 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 }; - std::string key1_str(key1, key1 + sizeof(key1) / sizeof(key1[0])); + uint8_t 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 key1_str(reinterpret_cast(key1)); json j = key1_str; CHECK_THROWS_AS(j.dump(), json::type_error&); CHECK_THROWS_WITH(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E"); From 0cd120f7e1f8cce7912f90bcc2846a209b8dc065 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 23 Jul 2020 14:06:09 +0200 Subject: [PATCH 12/17] :rotating_light: fix UBSAN warning --- test/src/unit-msgpack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/unit-msgpack.cpp b/test/src/unit-msgpack.cpp index 9275ad5e..c3761fb5 100644 --- a/test/src/unit-msgpack.cpp +++ b/test/src/unit-msgpack.cpp @@ -515,7 +515,7 @@ TEST_CASE("MessagePack") (static_cast(result[2]) << 020) + (static_cast(result[3]) << 010) + static_cast(result[4]); - CHECK(restored == i); + CHECK(static_cast(restored) == i); // roundtrip CHECK(json::from_msgpack(result) == j); From 59cb7674be9d4ae4bbb2b41906e64f3acb9c245e Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 23 Jul 2020 14:15:20 +0200 Subject: [PATCH 13/17] :memo: update documentation --- doc/mkdocs/docs/features/arbitrary_types.md | 4 ++++ doc/mkdocs/docs/features/macros.md | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/doc/mkdocs/docs/features/arbitrary_types.md b/doc/mkdocs/docs/features/arbitrary_types.md index 7bd7adf7..23913bba 100644 --- a/doc/mkdocs/docs/features/arbitrary_types.md +++ b/doc/mkdocs/docs/features/arbitrary_types.md @@ -92,6 +92,10 @@ There are two macros to make your life easier as long as you (1) want to use a J In both macros, the first parameter is the name of the class/struct, and all remaining parameters name the members. +!!! note + + At most 64 member variables can be passed to `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` or `NLOHMANN_DEFINE_TYPE_INTRUSIVE`. + ??? example The `to_json`/`from_json` functions for the `person` struct above can be created with: diff --git a/doc/mkdocs/docs/features/macros.md b/doc/mkdocs/docs/features/macros.md index 7147be7e..48a5159b 100644 --- a/doc/mkdocs/docs/features/macros.md +++ b/doc/mkdocs/docs/features/macros.md @@ -32,6 +32,26 @@ This macro overrides `#!cpp try` calls inside the library. It has no arguments a See [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example. +## `JSON_USE_IMPLICIT_CONVERSIONS` + +When defined to `0`, implicit conversions are switched off. By default, implicit conversions are switched on. + +??? example + + This is an example for an implicit conversion: + + ```cpp + json j = "Hello, world!"; + std::string s = j; + ``` + + When `JSON_USE_IMPLICIT_CONVERSIONS` is defined to `0`, the code above does no longer compile. Instead, it must be written like this: + + ```cpp + json j = "Hello, world!"; + auto s = j.get(); + ``` + ## `NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)` This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object. From 27232455c83609f2dd0953837c366d031a5ea474 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 23 Jul 2020 14:17:02 +0200 Subject: [PATCH 14/17] :memo: update documentation --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c1463349..eb9c268e 100644 --- a/README.md +++ b/README.md @@ -762,6 +762,7 @@ Supported types can be implicitly converted to JSON values. It is recommended to **NOT USE** implicit conversions **FROM** a JSON value. You can find more details about this recommendation [here](https://www.github.com/nlohmann/json/issues/958). +You can switch off implicit conversions by defining `JSON_USE_IMPLICIT_CONVERSIONS` to `0` before including the `json.hpp` header. When using CMake, you can also achieve this by setting the option `JSON_ImplicitConversions` to `OFF`. ```cpp // strings From 3c7dc635e7690f76fe49d2d1b5dcd588d6e95c81 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 23 Jul 2020 14:19:57 +0200 Subject: [PATCH 15/17] :see_no_evil: extend ignore list --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index bec7f598..7e5a881e 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,7 @@ benchmarks/files/numbers/*.json .wsjcpp/* .idea -cmake-build-debug +/cmake-build-* test/test-* /.vs @@ -32,3 +32,4 @@ doc/mkdocs/docs/images doc/mkdocs/docs/examples doc/mkdocs/site doc/mkdocs/docs/__pycache__/ +doc/xml From 0f22ed0b5b03c60b166b1b6ee19bed67f4063581 Mon Sep 17 00:00:00 2001 From: Jonas Wittbrodt Date: Thu, 23 Jul 2020 19:24:21 +0200 Subject: [PATCH 16/17] added inline to DEFINE_TYPE macro --- include/nlohmann/detail/macro_scope.hpp | 4 ++-- single_include/nlohmann/json.hpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/nlohmann/detail/macro_scope.hpp b/include/nlohmann/detail/macro_scope.hpp index c32a46d1..b6fea922 100644 --- a/include/nlohmann/detail/macro_scope.hpp +++ b/include/nlohmann/detail/macro_scope.hpp @@ -282,8 +282,8 @@ @since version 3.9.0 */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + inline void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } #ifndef JSON_USE_IMPLICIT_CONVERSIONS #define JSON_USE_IMPLICIT_CONVERSIONS 1 diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 0b7d2411..33dee5f5 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -2299,8 +2299,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP @since version 3.9.0 */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + inline void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } #ifndef JSON_USE_IMPLICIT_CONVERSIONS #define JSON_USE_IMPLICIT_CONVERSIONS 1 @@ -16501,7 +16501,7 @@ class basic_json detail::parser_callback_tcb = nullptr, const bool allow_exceptions = true, const bool ignore_comments = false - ) + ) { return ::nlohmann::detail::parser(std::move(adapter), std::move(cb), allow_exceptions, ignore_comments); @@ -25043,7 +25043,7 @@ template<> inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( is_nothrow_move_constructible::value&& is_nothrow_move_assignable::value - ) +) { j1.swap(j2); } From 480ad529e38bc895ad7169c943fecbf7ae911d5a Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Fri, 24 Jul 2020 14:18:39 +0200 Subject: [PATCH 17/17] :bug: fix bug in CBOR tag handling --- .../nlohmann/detail/input/binary_reader.hpp | 48 ++++++++++--------- single_include/nlohmann/json.hpp | 48 ++++++++++--------- test/src/unit-cbor.cpp | 21 ++++++++ 3 files changed, 73 insertions(+), 44 deletions(-) diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 72e652a4..edd4c4f7 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -393,14 +393,14 @@ class binary_reader /*! @param[in] get_char whether a new character should be retrieved from the - input (true, default) or whether the last read - character should be considered instead + input (true) or whether the last read character should + be considered instead (false) @param[in] tag_handler how CBOR tags should be treated @return whether a valid CBOR value was passed to the SAX parser */ - bool parse_cbor_internal(const bool get_char = true, - cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) + bool parse_cbor_internal(const bool get_char, + const cbor_tag_handler_t tag_handler) { switch (get_char ? get() : current) { @@ -606,34 +606,34 @@ class binary_reader case 0x95: case 0x96: case 0x97: - return get_cbor_array(static_cast(static_cast(current) & 0x1Fu)); + return get_cbor_array(static_cast(static_cast(current) & 0x1Fu), tag_handler); case 0x98: // array (one-byte uint8_t for n follows) { std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); } case 0x99: // array (two-byte uint16_t for n follow) { std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); } case 0x9A: // array (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); } case 0x9B: // array (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); } case 0x9F: // array (indefinite length) - return get_cbor_array(std::size_t(-1)); + return get_cbor_array(std::size_t(-1), tag_handler); // map (0x00..0x17 pairs of data items follow) case 0xA0: @@ -660,34 +660,34 @@ class binary_reader case 0xB5: case 0xB6: case 0xB7: - return get_cbor_object(static_cast(static_cast(current) & 0x1Fu)); + return get_cbor_object(static_cast(static_cast(current) & 0x1Fu), tag_handler); case 0xB8: // map (one-byte uint8_t for n follows) { std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); } case 0xB9: // map (two-byte uint16_t for n follow) { std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); } case 0xBA: // map (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); } case 0xBB: // map (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); } case 0xBF: // map (indefinite length) - return get_cbor_object(std::size_t(-1)); + return get_cbor_object(std::size_t(-1), tag_handler); case 0xC6: // tagged item case 0xC7: @@ -1030,9 +1030,11 @@ class binary_reader /*! @param[in] len the length of the array or std::size_t(-1) for an array of indefinite size + @param[in] tag_handler how CBOR tags should be treated @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) { if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) { @@ -1043,7 +1045,7 @@ class binary_reader { for (std::size_t i = 0; i < len; ++i) { - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) { return false; } @@ -1053,7 +1055,7 @@ class binary_reader { while (get() != 0xFF) { - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false))) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler))) { return false; } @@ -1066,9 +1068,11 @@ class binary_reader /*! @param[in] len the length of the object or std::size_t(-1) for an object of indefinite size + @param[in] tag_handler how CBOR tags should be treated @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) { if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) { @@ -1086,7 +1090,7 @@ class binary_reader return false; } - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) { return false; } @@ -1102,7 +1106,7 @@ class binary_reader return false; } - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) { return false; } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 0b7d2411..069bfc57 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -6402,14 +6402,14 @@ class binary_reader /*! @param[in] get_char whether a new character should be retrieved from the - input (true, default) or whether the last read - character should be considered instead + input (true) or whether the last read character should + be considered instead (false) @param[in] tag_handler how CBOR tags should be treated @return whether a valid CBOR value was passed to the SAX parser */ - bool parse_cbor_internal(const bool get_char = true, - cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) + bool parse_cbor_internal(const bool get_char, + const cbor_tag_handler_t tag_handler) { switch (get_char ? get() : current) { @@ -6615,34 +6615,34 @@ class binary_reader case 0x95: case 0x96: case 0x97: - return get_cbor_array(static_cast(static_cast(current) & 0x1Fu)); + return get_cbor_array(static_cast(static_cast(current) & 0x1Fu), tag_handler); case 0x98: // array (one-byte uint8_t for n follows) { std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); } case 0x99: // array (two-byte uint16_t for n follow) { std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); } case 0x9A: // array (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); } case 0x9B: // array (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); } case 0x9F: // array (indefinite length) - return get_cbor_array(std::size_t(-1)); + return get_cbor_array(std::size_t(-1), tag_handler); // map (0x00..0x17 pairs of data items follow) case 0xA0: @@ -6669,34 +6669,34 @@ class binary_reader case 0xB5: case 0xB6: case 0xB7: - return get_cbor_object(static_cast(static_cast(current) & 0x1Fu)); + return get_cbor_object(static_cast(static_cast(current) & 0x1Fu), tag_handler); case 0xB8: // map (one-byte uint8_t for n follows) { std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); } case 0xB9: // map (two-byte uint16_t for n follow) { std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); } case 0xBA: // map (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); } case 0xBB: // map (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); } case 0xBF: // map (indefinite length) - return get_cbor_object(std::size_t(-1)); + return get_cbor_object(std::size_t(-1), tag_handler); case 0xC6: // tagged item case 0xC7: @@ -7039,9 +7039,11 @@ class binary_reader /*! @param[in] len the length of the array or std::size_t(-1) for an array of indefinite size + @param[in] tag_handler how CBOR tags should be treated @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) { if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) { @@ -7052,7 +7054,7 @@ class binary_reader { for (std::size_t i = 0; i < len; ++i) { - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) { return false; } @@ -7062,7 +7064,7 @@ class binary_reader { while (get() != 0xFF) { - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false))) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler))) { return false; } @@ -7075,9 +7077,11 @@ class binary_reader /*! @param[in] len the length of the object or std::size_t(-1) for an object of indefinite size + @param[in] tag_handler how CBOR tags should be treated @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) { if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) { @@ -7095,7 +7099,7 @@ class binary_reader return false; } - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) { return false; } @@ -7111,7 +7115,7 @@ class binary_reader return false; } - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal())) + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) { return false; } diff --git a/test/src/unit-cbor.cpp b/test/src/unit-cbor.cpp index 7eaba84a..96613fb5 100644 --- a/test/src/unit-cbor.cpp +++ b/test/src/unit-cbor.cpp @@ -2722,4 +2722,25 @@ TEST_CASE("Tagged values") CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error); } } + + SECTION("tagged binary") + { + // create a binary value of subtype 42 + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // convert to CBOR + const auto v = json::to_cbor(j); + CHECK(v == std::vector {0xA1, 0x66, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79, 0xD8, 0x2A, 0x44, 0xCA, 0xFE, 0xBA, 0xBE}); + + // parse error when parsing tagged value + CHECK_THROWS_AS(json::from_cbor(v), json::parse_error); + CHECK_THROWS_WITH(json::from_cbor(v), "[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: invalid byte: 0xD8"); + + // binary without subtype when tags are ignored + json jb = json::from_cbor(v, true, true, json::cbor_tag_handler_t::ignore); + CHECK(jb.is_object()); + CHECK(jb["binary"].is_binary()); + CHECK(!jb["binary"].get_binary().has_subtype()); + } }