Merge branch 'develop' of https://github.com/nlohmann/json into bon8

 Conflicts:
	doc/mkdocs/docs/api/basic_json/index.md
	doc/mkdocs/docs/features/binary_formats/bson.md
	doc/mkdocs/docs/features/binary_formats/index.md
	doc/mkdocs/mkdocs.yml
	include/nlohmann/json.hpp
	single_include/nlohmann/json.hpp
This commit is contained in:
Niels Lohmann
2021-12-31 14:53:13 +01:00
427 changed files with 6293 additions and 13280 deletions

View File

@@ -52,6 +52,21 @@ endif()
# one executable for each unit test file
#############################################################################
# check if compiler supports C++17
foreach(feature ${CMAKE_CXX_COMPILE_FEATURES})
if (${feature} STREQUAL cxx_std_17)
set(compiler_supports_cpp_17 TRUE)
endif()
endforeach()
# Clang only supports C++17 starting from Clang 5.0
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
unset(compiler_supports_cpp_17)
endif()
# MSVC 2015 (14.0) does not support C++17
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.1)
unset(compiler_supports_cpp_17)
endif()
file(GLOB files src/unit-*.cpp)
foreach(file ${files})
@@ -68,6 +83,42 @@ foreach(file ${files})
target_include_directories(${testcase} PRIVATE ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map)
target_link_libraries(${testcase} PRIVATE ${NLOHMANN_JSON_TARGET_NAME})
# add a copy with C++17 compilation
if (compiler_supports_cpp_17)
file(READ ${file} FILE_CONTENT)
string(FIND "${FILE_CONTENT}" "JSON_HAS_CPP_17" CPP_17_FOUND)
if(NOT ${CPP_17_FOUND} EQUAL -1)
add_executable(${testcase}_cpp17 $<TARGET_OBJECTS:doctest_main> ${file})
target_compile_definitions(${testcase}_cpp17 PRIVATE DOCTEST_CONFIG_SUPER_FAST_ASSERTS)
target_compile_options(${testcase}_cpp17 PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
)
target_include_directories(${testcase}_cpp17 PRIVATE ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map)
target_link_libraries(${testcase}_cpp17 PRIVATE ${NLOHMANN_JSON_TARGET_NAME})
target_compile_features(${testcase}_cpp17 PRIVATE cxx_std_17)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0 AND NOT MINGW)
# fix for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90050
target_link_libraries(${testcase}_cpp17 PRIVATE stdc++fs)
endif()
if (JSON_FastTests)
add_test(NAME "${testcase}_cpp17"
COMMAND ${testcase}_cpp17 ${DOCTEST_TEST_FILTER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
else()
add_test(NAME "${testcase}_cpp17"
COMMAND ${testcase}_cpp17 ${DOCTEST_TEST_FILTER} --no-skip
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
endif()
set_tests_properties("${testcase}_cpp17" PROPERTIES LABELS "all" FIXTURES_REQUIRED TEST_DATA)
endif()
endif()
if (JSON_FastTests)
add_test(NAME "${testcase}"
COMMAND ${testcase} ${DOCTEST_TEST_FILTER}

View File

@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.18)
project(json_cuda LANGUAGES CUDA)
add_executable(json_cuda json_cuda.cu)
target_include_directories(json_cuda PRIVATE ../../include)
target_compile_features(json_cuda PUBLIC cuda_std_11)
set_target_properties(json_cuda PROPERTIES
CUDA_EXTENSIONS OFF
CUDA_STANDARD_REQUIRED ON
)

View File

@@ -0,0 +1,7 @@
#include <nlohmann/json.hpp>
int main()
{
nlohmann::ordered_json json = {"Test"};
json.dump();
}

View File

@@ -41,11 +41,11 @@ TEST_CASE("byte_container_with_subtype")
nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>> container;
CHECK(!container.has_subtype());
CHECK(container.subtype() == subtype_type(-1));
CHECK(container.subtype() == static_cast<subtype_type>(-1));
container.clear_subtype();
CHECK(!container.has_subtype());
CHECK(container.subtype() == subtype_type(-1));
CHECK(container.subtype() == static_cast<subtype_type>(-1));
container.set_subtype(42);
CHECK(container.has_subtype());
@@ -60,7 +60,7 @@ TEST_CASE("byte_container_with_subtype")
container.clear_subtype();
CHECK(!container.has_subtype());
CHECK(container.subtype() == subtype_type(-1));
CHECK(container.subtype() == static_cast<subtype_type>(-1));
}
SECTION("comparisons")

View File

@@ -610,7 +610,7 @@ TEST_CASE("CBOR")
SECTION("-32768..-129 (int 16)")
{
for (int16_t i = -32768; i <= int16_t(-129); ++i)
for (int16_t i = -32768; i <= static_cast<std::int16_t>(-129); ++i)
{
CAPTURE(i)

View File

@@ -93,7 +93,7 @@ class SaxEventLogger
bool start_object(std::size_t elements)
{
if (elements == std::size_t(-1))
if (elements == static_cast<std::size_t>(-1))
{
events.emplace_back("start_object()");
}
@@ -118,7 +118,7 @@ class SaxEventLogger
bool start_array(std::size_t elements)
{
if (elements == std::size_t(-1))
if (elements == static_cast<std::size_t>(-1))
{
events.emplace_back("start_array()");
}

View File

@@ -93,7 +93,7 @@ struct SaxEventLogger : public nlohmann::json_sax<json>
bool start_object(std::size_t elements) override
{
if (elements == std::size_t(-1))
if (elements == static_cast<std::size_t>(-1))
{
events.emplace_back("start_object()");
}
@@ -118,7 +118,7 @@ struct SaxEventLogger : public nlohmann::json_sax<json>
bool start_array(std::size_t elements) override
{
if (elements == std::size_t(-1))
if (elements == static_cast<std::size_t>(-1))
{
events.emplace_back("start_array()");
}
@@ -148,7 +148,7 @@ struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger
{
bool start_object(std::size_t elements) override
{
if (elements == std::size_t(-1))
if (elements == static_cast<std::size_t>(-1))
{
events.emplace_back("start_object()");
}
@@ -173,7 +173,7 @@ struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
{
bool start_array(std::size_t elements) override
{
if (elements == std::size_t(-1))
if (elements == static_cast<std::size_t>(-1))
{
events.emplace_back("start_array()");
}

View File

@@ -97,6 +97,18 @@ TEST_CASE("Better diagnostics")
CHECK_THROWS_WITH_AS(_ = json::parse(""), "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error);
}
SECTION("Wrong type in update()")
{
json j = {{"foo", "bar"}};
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"]), "[json.exception.type_error.312] (/bla) cannot use update() with number", json::type_error);
}
}
TEST_CASE("Regression tests for extended diagnostics")
{
SECTION("Regression test for https://github.com/nlohmann/json/pull/2562#pullrequestreview-574858448")
{
CHECK_THROWS_WITH_AS(json({"0", "0"})[1].get<int>(), "[json.exception.type_error.302] (/1) type must be number, but is string", json::type_error);
@@ -110,7 +122,7 @@ TEST_CASE("Better diagnostics")
CHECK_THROWS_WITH_AS(j.unflatten(), "[json.exception.type_error.315] (/~1foo) values in object must be primitive", json::type_error);
}
SECTION("Regression test for https://github.com/nlohmann/json/issues/2838")
SECTION("Regression test for issue #2838 - Assertion failure when inserting into arrays with JSON_DIAGNOSTICS set")
{
// void push_back(basic_json&& val)
{
@@ -235,7 +247,7 @@ TEST_CASE("Better diagnostics")
}
}
SECTION("Regression test for https://github.com/nlohmann/json/issues/3032")
SECTION("Regression test for issue #3032 - Yet another assertion failure when inserting into arrays with JSON_DIAGNOSTICS set")
{
// reference operator[](size_type idx)
{

View File

@@ -31,10 +31,11 @@ SOFTWARE.
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using ordered_json = nlohmann::ordered_json;
#include <set>
TEST_CASE("hash")
TEST_CASE("hash<nlohmann::json>")
{
// Collect hashes for different JSON values and make sure that they are distinct
// We cannot compare against fixed values, because the implementation of
@@ -55,7 +56,7 @@ TEST_CASE("hash")
// number
hashes.insert(std::hash<json> {}(json(0)));
hashes.insert(std::hash<json> {}(json(unsigned(0))));
hashes.insert(std::hash<json> {}(json(static_cast<unsigned>(0))));
hashes.insert(std::hash<json> {}(json(-1)));
hashes.insert(std::hash<json> {}(json(0.0)));
@@ -82,3 +83,52 @@ TEST_CASE("hash")
CHECK(hashes.size() == 21);
}
TEST_CASE("hash<nlohmann::ordered_json>")
{
// Collect hashes for different JSON values and make sure that they are distinct
// We cannot compare against fixed values, because the implementation of
// std::hash may differ between compilers.
std::set<std::size_t> hashes;
// null
hashes.insert(std::hash<ordered_json> {}(ordered_json(nullptr)));
// boolean
hashes.insert(std::hash<ordered_json> {}(ordered_json(true)));
hashes.insert(std::hash<ordered_json> {}(ordered_json(false)));
// string
hashes.insert(std::hash<ordered_json> {}(ordered_json("")));
hashes.insert(std::hash<ordered_json> {}(ordered_json("foo")));
// number
hashes.insert(std::hash<ordered_json> {}(ordered_json(0)));
hashes.insert(std::hash<ordered_json> {}(ordered_json(static_cast<unsigned>(0))));
hashes.insert(std::hash<ordered_json> {}(ordered_json(-1)));
hashes.insert(std::hash<ordered_json> {}(ordered_json(0.0)));
hashes.insert(std::hash<ordered_json> {}(ordered_json(42.23)));
// array
hashes.insert(std::hash<ordered_json> {}(ordered_json::array()));
hashes.insert(std::hash<ordered_json> {}(ordered_json::array({1, 2, 3})));
// object
hashes.insert(std::hash<ordered_json> {}(ordered_json::object()));
hashes.insert(std::hash<ordered_json> {}(ordered_json::object({{"foo", "bar"}})));
// binary
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({})));
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({}, 0)));
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({}, 42)));
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({1, 2, 3})));
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({1, 2, 3}, 0)));
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({1, 2, 3}, 42)));
// discarded
hashes.insert(std::hash<ordered_json> {}(ordered_json(ordered_json::value_t::discarded)));
CHECK(hashes.size() == 21);
}

View File

@@ -796,64 +796,89 @@ TEST_CASE("modifiers")
SECTION("update()")
{
json j_object1 = {{"one", "eins"}, {"two", "zwei"}};
json j_object2 = {{"three", "drei"}, {"two", "zwo"}};
json j_array = {1, 2, 3, 4};
SECTION("const reference")
SECTION("non-recursive (default)")
{
SECTION("proper usage")
{
j_object1.update(j_object2);
CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwo"}, {"three", "drei"}}));
json j_object1 = {{"one", "eins"}, {"two", "zwei"}};
json j_object2 = {{"three", "drei"}, {"two", "zwo"}};
json j_array = {1, 2, 3, 4};
json j_null;
j_null.update(j_object2);
CHECK(j_null == j_object2);
SECTION("const reference")
{
SECTION("proper usage")
{
j_object1.update(j_object2);
CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwo"}, {"three", "drei"}}));
json j_null;
j_null.update(j_object2);
CHECK(j_null == j_object2);
}
SECTION("wrong types")
{
CHECK_THROWS_AS(j_array.update(j_object1), json::type_error&);
CHECK_THROWS_WITH(j_array.update(j_object1), "[json.exception.type_error.312] cannot use update() with array");
CHECK_THROWS_AS(j_object1.update(j_array), json::type_error&);
CHECK_THROWS_WITH(j_object1.update(j_array), "[json.exception.type_error.312] cannot use update() with array");
}
}
SECTION("wrong types")
SECTION("iterator range")
{
CHECK_THROWS_AS(j_array.update(j_object1), json::type_error&);
CHECK_THROWS_WITH(j_array.update(j_object1), "[json.exception.type_error.312] cannot use update() with array");
SECTION("proper usage")
{
j_object1.update(j_object2.begin(), j_object2.end());
CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwo"}, {"three", "drei"}}));
CHECK_THROWS_AS(j_object1.update(j_array), json::type_error&);
CHECK_THROWS_WITH(j_object1.update(j_array), "[json.exception.type_error.312] cannot use update() with array");
json j_null;
j_null.update(j_object2.begin(), j_object2.end());
CHECK(j_null == j_object2);
}
SECTION("empty range")
{
j_object1.update(j_object2.begin(), j_object2.begin());
CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwei"}}));
}
SECTION("invalid iterators")
{
json j_other_array2 = {"first", "second"};
CHECK_THROWS_AS(j_array.update(j_object2.begin(), j_object2.end()), json::type_error&);
CHECK_THROWS_AS(j_object1.update(j_object1.begin(), j_object2.end()), json::invalid_iterator&);
CHECK_THROWS_AS(j_object1.update(j_array.begin(), j_array.end()), json::type_error&);
CHECK_THROWS_WITH(j_array.update(j_object2.begin(), j_object2.end()),
"[json.exception.type_error.312] cannot use update() with array");
CHECK_THROWS_WITH(j_object1.update(j_object1.begin(), j_object2.end()),
"[json.exception.invalid_iterator.210] iterators do not fit");
CHECK_THROWS_WITH(j_object1.update(j_array.begin(), j_array.end()),
"[json.exception.type_error.312] cannot use update() with array");
}
}
}
SECTION("iterator range")
SECTION("recursive")
{
SECTION("proper usage")
SECTION("const reference")
{
j_object1.update(j_object2.begin(), j_object2.end());
CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwo"}, {"three", "drei"}}));
SECTION("extend object")
{
json j1 = {{"string", "s"}, {"numbers", {{"one", 1}}}};
json j2 = {{"string", "t"}, {"numbers", {{"two", 2}}}};
j1.update(j2, true);
CHECK(j1 == json({{"string", "t"}, {"numbers", {{"one", 1}, {"two", 2}}}}));
}
json j_null;
j_null.update(j_object2.begin(), j_object2.end());
CHECK(j_null == j_object2);
}
SECTION("empty range")
{
j_object1.update(j_object2.begin(), j_object2.begin());
CHECK(j_object1 == json({{"one", "eins"}, {"two", "zwei"}}));
}
SECTION("invalid iterators")
{
json j_other_array2 = {"first", "second"};
CHECK_THROWS_AS(j_array.update(j_object2.begin(), j_object2.end()), json::type_error&);
CHECK_THROWS_AS(j_object1.update(j_object1.begin(), j_object2.end()), json::invalid_iterator&);
CHECK_THROWS_AS(j_object1.update(j_array.begin(), j_array.end()), json::invalid_iterator&);
CHECK_THROWS_WITH(j_array.update(j_object2.begin(), j_object2.end()),
"[json.exception.type_error.312] cannot use update() with array");
CHECK_THROWS_WITH(j_object1.update(j_object1.begin(), j_object2.end()),
"[json.exception.invalid_iterator.210] iterators do not fit");
CHECK_THROWS_WITH(j_object1.update(j_array.begin(), j_array.end()),
"[json.exception.invalid_iterator.202] iterators first and last must point to objects");
SECTION("replace object")
{
json j1 = {{"string", "s"}, {"numbers", {{"one", 1}}}};
json j2 = {{"string", "t"}, {"numbers", 1}};
j1.update(j2, true);
CHECK(j1 == json({{"string", "t"}, {"numbers", 1}}));
}
}
}
}

View File

@@ -446,7 +446,7 @@ TEST_CASE("MessagePack")
SECTION("-32768..-129 (int 16)")
{
for (int16_t i = -32768; i <= int16_t(-129); ++i)
for (int16_t i = -32768; i <= static_cast<std::int16_t>(-129); ++i)
{
CAPTURE(i)

View File

@@ -210,6 +210,45 @@ TEST_CASE("ordered_map")
++it2;
CHECK(it2 == om.end());
}
SECTION("with iterator pair")
{
SECTION("range in the middle")
{
// need more elements
om["vier"] = "four";
om["fünf"] = "five";
// delete "zwei" and "drei"
auto it = om.erase(om.begin() + 1, om.begin() + 3);
CHECK(it->first == "vier");
CHECK(om.size() == 3);
}
SECTION("range at the beginning")
{
// need more elements
om["vier"] = "four";
om["fünf"] = "five";
// delete "eins" and "zwei"
auto it = om.erase(om.begin(), om.begin() + 2);
CHECK(it->first == "drei");
CHECK(om.size() == 3);
}
SECTION("range at the end")
{
// need more elements
om["vier"] = "four";
om["fünf"] = "five";
// delete "vier" and "fünf"
auto it = om.erase(om.begin() + 3, om.end());
CHECK(it == om.end());
CHECK(om.size() == 3);
}
}
}
SECTION("count")

View File

@@ -170,7 +170,7 @@ TEST_CASE("regression tests 1")
json::number_float_t f1{j1};
CHECK(std::isnan(f1));
json j2 = json::number_float_t(NAN);
json j2 = static_cast<json::number_float_t>(NAN);
CHECK(j2.is_number_float());
json::number_float_t f2{j2};
CHECK(std::isnan(f2));
@@ -183,7 +183,7 @@ TEST_CASE("regression tests 1")
json::number_float_t f1{j1};
CHECK(!std::isfinite(f1));
json j2 = json::number_float_t(INFINITY);
json j2 = static_cast<json::number_float_t>(INFINITY);
CHECK(j2.is_number_float());
json::number_float_t f2{j2};
CHECK(!std::isfinite(f2));
@@ -205,7 +205,7 @@ TEST_CASE("regression tests 1")
// check if the actual value was stored
CHECK(j2 == 102);
static_assert(std::is_same<decltype(anon_enum_value), decltype(u)>::value, "");
static_assert(std::is_same<decltype(anon_enum_value), decltype(u)>::value, "types must be the same");
j.push_back(json::object(
{
@@ -567,17 +567,17 @@ TEST_CASE("regression tests 1")
SECTION("issue #378 - locale-independent num-to-str")
{
setlocale(LC_NUMERIC, "de_DE.UTF-8");
static_cast<void>(setlocale(LC_NUMERIC, "de_DE.UTF-8"));
// verify that dumped correctly with '.' and no grouping
const json j1 = 12345.67;
CHECK(json(12345.67).dump() == "12345.67");
setlocale(LC_NUMERIC, "C");
static_cast<void>(setlocale(LC_NUMERIC, "C"));
}
SECTION("issue #379 - locale-independent str-to-num")
{
setlocale(LC_NUMERIC, "de_DE.UTF-8");
static_cast<void>(setlocale(LC_NUMERIC, "de_DE.UTF-8"));
// verify that parsed correctly despite using strtod internally
CHECK(json::parse("3.14").get<double>() == 3.14);
@@ -910,7 +910,7 @@ TEST_CASE("regression tests 1")
++i;
}
std::remove("test.json");
static_cast<void>(std::remove("test.json"));
}
}

View File

@@ -47,10 +47,82 @@ using ordered_json = nlohmann::ordered_json;
#endif
#ifdef JSON_HAS_CPP_17
#include <filesystem>
#include <variant>
#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
#if defined(__cpp_lib_filesystem)
#define JSON_HAS_FILESYSTEM 1
#elif defined(__cpp_lib_experimental_filesystem)
#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
#elif !defined(__has_include)
#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
#elif __has_include(<filesystem>)
#define JSON_HAS_FILESYSTEM 1
#elif __has_include(<experimental/filesystem>)
#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
#endif
// std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
#if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
#undef JSON_HAS_FILESYSTEM
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
#endif
// no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
#if defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)
#undef JSON_HAS_FILESYSTEM
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
#endif
// no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
#if defined(__clang_major__) && __clang_major__ < 7
#undef JSON_HAS_FILESYSTEM
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
#endif
// no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
#if defined(_MSC_VER) && _MSC_VER < 1940
#undef JSON_HAS_FILESYSTEM
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
#endif
// no filesystem support before iOS 13
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
#undef JSON_HAS_FILESYSTEM
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
#endif
// no filesystem support before macOS Catalina
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
#undef JSON_HAS_FILESYSTEM
#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
#endif
#endif
#endif
#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
#endif
#ifndef JSON_HAS_FILESYSTEM
#define JSON_HAS_FILESYSTEM 0
#endif
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
#include <experimental/filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::experimental::filesystem;
} // namespace nlohmann::detail
#elif JSON_HAS_FILESYSTEM
#include <filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::filesystem;
} // namespace nlohmann::detail
#endif
#ifdef JSON_HAS_CPP_20
#include <span>
#endif
@@ -351,9 +423,7 @@ TEST_CASE("regression tests 2")
#ifdef JSON_HAS_CPP_17
SECTION("issue #1292 - Serializing std::variant causes stack overflow")
{
static_assert(
!std::is_constructible<json, std::variant<int, float>>::value,
"");
static_assert(!std::is_constructible<json, std::variant<int, float>>::value, "unexpected value");
}
#endif
@@ -492,15 +562,15 @@ TEST_CASE("regression tests 2")
SECTION("issue #1805 - A pair<T1, T2> is json constructible only if T1 and T2 are json constructible")
{
static_assert(!std::is_constructible<json, std::pair<std::string, NotSerializableData>>::value, "");
static_assert(!std::is_constructible<json, std::pair<NotSerializableData, std::string>>::value, "");
static_assert(std::is_constructible<json, std::pair<int, std::string>>::value, "");
static_assert(!std::is_constructible<json, std::pair<std::string, NotSerializableData>>::value, "unexpected result");
static_assert(!std::is_constructible<json, std::pair<NotSerializableData, std::string>>::value, "unexpected result");
static_assert(std::is_constructible<json, std::pair<int, std::string>>::value, "unexpected result");
}
SECTION("issue #1825 - A tuple<Args..> is json constructible only if all T in Args are json constructible")
{
static_assert(!std::is_constructible<json, std::tuple<std::string, NotSerializableData>>::value, "");
static_assert(!std::is_constructible<json, std::tuple<NotSerializableData, std::string>>::value, "");
static_assert(std::is_constructible<json, std::tuple<int, std::string>>::value, "");
static_assert(!std::is_constructible<json, std::tuple<std::string, NotSerializableData>>::value, "unexpected result");
static_assert(!std::is_constructible<json, std::tuple<NotSerializableData, std::string>>::value, "unexpected result");
static_assert(std::is_constructible<json, std::tuple<int, std::string>>::value, "unexpected result");
}
SECTION("issue #1983 - JSON patch diff for op=add formation is not as per standard (RFC 6902)")
@@ -532,7 +602,7 @@ TEST_CASE("regression tests 2")
auto val2 = j.value("y", defval);
}
SECTION("issue #2293 - eof doesnt cause parsing to stop")
SECTION("issue #2293 - eof doesn't cause parsing to stop")
{
std::vector<uint8_t> data =
{
@@ -697,7 +767,7 @@ TEST_CASE("regression tests 2")
SECTION("issue #2825 - Properly constrain the basic_json conversion operator")
{
static_assert(std::is_copy_assignable<nlohmann::ordered_json>::value, "");
static_assert(std::is_copy_assignable<nlohmann::ordered_json>::value, "ordered_json must be copy assignable");
}
SECTION("issue #2958 - Inserting in unordered json using a pointer retains the leading slash")
@@ -728,14 +798,16 @@ TEST_CASE("regression tests 2")
CHECK(j == k);
}
#ifdef JSON_HAS_CPP_17
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
SECTION("issue #3070 - Version 3.10.3 breaks backward-compatibility with 3.10.2 ")
{
std::filesystem::path text_path("/tmp/text.txt");
nlohmann::detail::std_fs::path text_path("/tmp/text.txt");
json j(text_path);
const auto j_path = j.get<std::filesystem::path>();
const auto j_path = j.get<nlohmann::detail::std_fs::path>();
CHECK(j_path == text_path);
CHECK_THROWS_WITH_AS(nlohmann::detail::std_fs::path(json(1)), "[json.exception.type_error.302] type must be string, but is number", json::type_error);
}
#endif
@@ -746,6 +818,23 @@ TEST_CASE("regression tests 2")
std::vector<FooBar> foo;
j.get_to(foo);
}
SECTION("issue #3108 - ordered_json doesn't support range based erase")
{
ordered_json j = {1, 2, 2, 4};
auto last = std::unique(j.begin(), j.end());
j.erase(last, j.end());
CHECK(j.dump() == "[1,2,4]");
j.erase(std::remove_if(j.begin(), j.end(), [](const ordered_json & val)
{
return val == 2;
}), j.end());
CHECK(j.dump() == "[1,4]");
}
}
DOCTEST_CLANG_SUPPRESS_WARNING_POP