🚶 use Clang-Format

This commit is contained in:
Niels Lohmann
2023-11-29 15:02:51 +01:00
parent 9cca280a4d
commit 311ad0b877
123 changed files with 17740 additions and 15765 deletions
+1 -1
View File
@@ -18,7 +18,7 @@
#define STRINGIZE(x) STRINGIZE_EX(x)
template<typename T>
std::string namespace_name(std::string ns, T* /*unused*/ = nullptr) // NOLINT(performance-unnecessary-value-param)
std::string namespace_name(std::string ns, T* /*unused*/ = nullptr) // NOLINT(performance-unnecessary-value-param)
{
#if DOCTEST_MSVC && !DOCTEST_CLANG
ns = __FUNCSIG__;
+1 -1
View File
@@ -11,7 +11,7 @@
#include "config.hpp"
// 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_END }
#include <nlohmann/json_fwd.hpp>
+4 -4
View File
@@ -20,13 +20,13 @@ TEST_CASE("default namespace")
{
std::string expected = "nlohmann::json_abi";
#if JSON_DIAGNOSTICS
#if JSON_DIAGNOSTICS
expected += "_diag";
#endif
#endif
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
expected += "_ldvcmp";
#endif
#endif
expected += "_v" STRINGIZE(NLOHMANN_JSON_VERSION_MAJOR);
expected += "_" STRINGIZE(NLOHMANN_JSON_VERSION_MINOR);
+4 -4
View File
@@ -21,13 +21,13 @@ TEST_CASE("default namespace without version component")
{
std::string expected = "nlohmann::json_abi";
#if JSON_DIAGNOSTICS
#if JSON_DIAGNOSTICS
expected += "_diag";
#endif
#endif
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
expected += "_ldvcmp";
#endif
#endif
expected += "::basic_json";
+39 -39
View File
@@ -7,11 +7,11 @@
// SPDX-License-Identifier: MIT
#include <benchmark/benchmark.h>
#include <nlohmann/json.hpp>
#include <fstream>
#include <nlohmann/json.hpp>
#include <numeric>
#include <vector>
#include <test_data.hpp>
#include <vector>
using json = nlohmann::json;
@@ -39,13 +39,13 @@ static void ParseFile(benchmark::State& state, const char* filename)
std::ifstream file(filename, std::ios::binary | std::ios::ate);
state.SetBytesProcessed(state.iterations() * file.tellg());
}
BENCHMARK_CAPTURE(ParseFile, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json");
BENCHMARK_CAPTURE(ParseFile, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json");
BENCHMARK_CAPTURE(ParseFile, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json");
BENCHMARK_CAPTURE(ParseFile, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json");
BENCHMARK_CAPTURE(ParseFile, floats, TEST_DATA_DIRECTORY "/regression/floats.json");
BENCHMARK_CAPTURE(ParseFile, signed_ints, TEST_DATA_DIRECTORY "/regression/signed_ints.json");
BENCHMARK_CAPTURE(ParseFile, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json");
BENCHMARK_CAPTURE(ParseFile, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json");
BENCHMARK_CAPTURE(ParseFile, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json");
BENCHMARK_CAPTURE(ParseFile, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json");
BENCHMARK_CAPTURE(ParseFile, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json");
BENCHMARK_CAPTURE(ParseFile, floats, TEST_DATA_DIRECTORY "/regression/floats.json");
BENCHMARK_CAPTURE(ParseFile, signed_ints, TEST_DATA_DIRECTORY "/regression/signed_ints.json");
BENCHMARK_CAPTURE(ParseFile, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json");
BENCHMARK_CAPTURE(ParseFile, small_signed_ints, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json");
//////////////////////////////////////////////////////////////////////////////
@@ -72,13 +72,13 @@ static void ParseString(benchmark::State& state, const char* filename)
state.SetBytesProcessed(state.iterations() * str.size());
}
BENCHMARK_CAPTURE(ParseString, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json");
BENCHMARK_CAPTURE(ParseString, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json");
BENCHMARK_CAPTURE(ParseString, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json");
BENCHMARK_CAPTURE(ParseString, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json");
BENCHMARK_CAPTURE(ParseString, floats, TEST_DATA_DIRECTORY "/regression/floats.json");
BENCHMARK_CAPTURE(ParseString, signed_ints, TEST_DATA_DIRECTORY "/regression/signed_ints.json");
BENCHMARK_CAPTURE(ParseString, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json");
BENCHMARK_CAPTURE(ParseString, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json");
BENCHMARK_CAPTURE(ParseString, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json");
BENCHMARK_CAPTURE(ParseString, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json");
BENCHMARK_CAPTURE(ParseString, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json");
BENCHMARK_CAPTURE(ParseString, floats, TEST_DATA_DIRECTORY "/regression/floats.json");
BENCHMARK_CAPTURE(ParseString, signed_ints, TEST_DATA_DIRECTORY "/regression/signed_ints.json");
BENCHMARK_CAPTURE(ParseString, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json");
BENCHMARK_CAPTURE(ParseString, small_signed_ints, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json");
//////////////////////////////////////////////////////////////////////////////
@@ -98,22 +98,22 @@ static void Dump(benchmark::State& state, const char* filename, int indent)
state.SetBytesProcessed(state.iterations() * j.dump(indent).size());
}
BENCHMARK_CAPTURE(Dump, jeopardy / -, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json", -1);
BENCHMARK_CAPTURE(Dump, jeopardy / 4, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json", 4);
BENCHMARK_CAPTURE(Dump, canada / -, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json", -1);
BENCHMARK_CAPTURE(Dump, canada / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json", 4);
BENCHMARK_CAPTURE(Dump, citm_catalog / -, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json", -1);
BENCHMARK_CAPTURE(Dump, citm_catalog / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json", 4);
BENCHMARK_CAPTURE(Dump, twitter / -, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json", -1);
BENCHMARK_CAPTURE(Dump, twitter / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json", 4);
BENCHMARK_CAPTURE(Dump, floats / -, TEST_DATA_DIRECTORY "/regression/floats.json", -1);
BENCHMARK_CAPTURE(Dump, floats / 4, TEST_DATA_DIRECTORY "/regression/floats.json", 4);
BENCHMARK_CAPTURE(Dump, signed_ints / -, TEST_DATA_DIRECTORY "/regression/signed_ints.json", -1);
BENCHMARK_CAPTURE(Dump, signed_ints / 4, TEST_DATA_DIRECTORY "/regression/signed_ints.json", 4);
BENCHMARK_CAPTURE(Dump, unsigned_ints / -, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json", -1);
BENCHMARK_CAPTURE(Dump, unsigned_ints / 4, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json", 4);
BENCHMARK_CAPTURE(Dump, small_signed_ints / -, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json", -1);
BENCHMARK_CAPTURE(Dump, small_signed_ints / 4, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json", 4);
BENCHMARK_CAPTURE(Dump, jeopardy / -, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json", -1);
BENCHMARK_CAPTURE(Dump, jeopardy / 4, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json", 4);
BENCHMARK_CAPTURE(Dump, canada / -, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json", -1);
BENCHMARK_CAPTURE(Dump, canada / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json", 4);
BENCHMARK_CAPTURE(Dump, citm_catalog / -, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json", -1);
BENCHMARK_CAPTURE(Dump, citm_catalog / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json", 4);
BENCHMARK_CAPTURE(Dump, twitter / -, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json", -1);
BENCHMARK_CAPTURE(Dump, twitter / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json", 4);
BENCHMARK_CAPTURE(Dump, floats / -, TEST_DATA_DIRECTORY "/regression/floats.json", -1);
BENCHMARK_CAPTURE(Dump, floats / 4, TEST_DATA_DIRECTORY "/regression/floats.json", 4);
BENCHMARK_CAPTURE(Dump, signed_ints / -, TEST_DATA_DIRECTORY "/regression/signed_ints.json", -1);
BENCHMARK_CAPTURE(Dump, signed_ints / 4, TEST_DATA_DIRECTORY "/regression/signed_ints.json", 4);
BENCHMARK_CAPTURE(Dump, unsigned_ints / -, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json", -1);
BENCHMARK_CAPTURE(Dump, unsigned_ints / 4, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json", 4);
BENCHMARK_CAPTURE(Dump, small_signed_ints / -, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json", -1);
BENCHMARK_CAPTURE(Dump, small_signed_ints / 4, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json", 4);
//////////////////////////////////////////////////////////////////////////////
// serialize CBOR
@@ -131,13 +131,13 @@ static void ToCbor(benchmark::State& state, const char* filename)
state.SetBytesProcessed(state.iterations() * json::to_cbor(j).size());
}
BENCHMARK_CAPTURE(ToCbor, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json");
BENCHMARK_CAPTURE(ToCbor, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json");
BENCHMARK_CAPTURE(ToCbor, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json");
BENCHMARK_CAPTURE(ToCbor, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json");
BENCHMARK_CAPTURE(ToCbor, floats, TEST_DATA_DIRECTORY "/regression/floats.json");
BENCHMARK_CAPTURE(ToCbor, signed_ints, TEST_DATA_DIRECTORY "/regression/signed_ints.json");
BENCHMARK_CAPTURE(ToCbor, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json");
BENCHMARK_CAPTURE(ToCbor, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json");
BENCHMARK_CAPTURE(ToCbor, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json");
BENCHMARK_CAPTURE(ToCbor, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json");
BENCHMARK_CAPTURE(ToCbor, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json");
BENCHMARK_CAPTURE(ToCbor, floats, TEST_DATA_DIRECTORY "/regression/floats.json");
BENCHMARK_CAPTURE(ToCbor, signed_ints, TEST_DATA_DIRECTORY "/regression/signed_ints.json");
BENCHMARK_CAPTURE(ToCbor, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json");
BENCHMARK_CAPTURE(ToCbor, small_signed_ints, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json");
//////////////////////////////////////////////////////////////////////////////
@@ -6,7 +6,8 @@
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#include <nlohmann/json.hpp>
#include "Foo.hpp"
#include <nlohmann/json.hpp>
class Bar : public Foo {};
class Bar : public Foo
{};
@@ -9,4 +9,5 @@
#pragma once
#include <nlohmann/json.hpp>
class Foo {};
class Foo
{};
+1 -1
View File
@@ -12,9 +12,9 @@ an implementation of the `LLVMFuzzerTestOneInput` function which processes a
passed byte array.
*/
#include <vector> // for vector
#include <cstdint> // for uint8_t
#include <iostream> // for cin
#include <vector> // for vector
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
+1 -1
View File
@@ -26,8 +26,8 @@ drivers.
*/
#include <iostream>
#include <sstream>
#include <nlohmann/json.hpp>
#include <sstream>
using json = nlohmann::json;
+1 -1
View File
@@ -20,8 +20,8 @@ drivers.
*/
#include <iostream>
#include <sstream>
#include <nlohmann/json.hpp>
#include <sstream>
using json = nlohmann::json;
+1 -1
View File
@@ -20,8 +20,8 @@ drivers.
*/
#include <iostream>
#include <sstream>
#include <nlohmann/json.hpp>
#include <sstream>
using json = nlohmann::json;
+1 -1
View File
@@ -21,8 +21,8 @@ drivers.
*/
#include <iostream>
#include <sstream>
#include <nlohmann/json.hpp>
#include <sstream>
using json = nlohmann::json;
+1 -1
View File
@@ -20,8 +20,8 @@ drivers.
*/
#include <iostream>
#include <sstream>
#include <nlohmann/json.hpp>
#include <sstream>
using json = nlohmann::json;
+1 -1
View File
@@ -26,8 +26,8 @@ drivers.
*/
#include <iostream>
#include <sstream>
#include <nlohmann/json.hpp>
#include <sstream>
using json = nlohmann::json;
+4 -5
View File
@@ -8,13 +8,12 @@
#pragma once
#include <cstdio> // fopen, fclose, FILE
#include <memory> // unique_ptr
#include <test_data.hpp>
#include <cstdio> // fopen, fclose, FILE
#include <doctest.h>
#include <memory> // unique_ptr
#include <test_data.hpp>
namespace utils
{
namespace utils {
inline bool check_testsuite_downloaded()
{
+5 -6
View File
@@ -8,12 +8,11 @@
#pragma once
#include <cstdint> // uint8_t
#include <fstream> // ifstream, istreambuf_iterator, ios
#include <vector> // vector
#include <cstdint> // uint8_t
#include <fstream> // ifstream, istreambuf_iterator, ios
#include <vector> // vector
namespace utils
{
namespace utils {
inline std::vector<std::uint8_t> read_binary_file(const std::string& filename)
{
@@ -30,4 +29,4 @@ inline std::vector<std::uint8_t> read_binary_file(const std::string& filename)
return byte_vector;
}
} // namespace utils
} // namespace utils
+7 -7
View File
@@ -11,10 +11,10 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#include <climits> // SIZE_MAX
#include <limits> // numeric_limits
#include <climits> // SIZE_MAX
#include <limits> // numeric_limits
template <typename OfType, typename T, bool MinInRange, bool MaxInRange>
template<typename OfType, typename T, bool MinInRange, bool MaxInRange>
struct trait_test_arg
{
using of_type = OfType;
@@ -92,10 +92,10 @@ TEST_CASE("32bit")
REQUIRE(SIZE_MAX == 0xffffffff);
}
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::uint32_t, true, true>, \
trait_test_arg<std::size_t, std::int64_t, false, false>, \
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::uint32_t, true, true>,
trait_test_arg<std::size_t, std::int64_t, false, false>,
trait_test_arg<std::size_t, std::uint64_t, true, false>);
TEST_CASE("BJData")
+23 -46
View File
@@ -21,36 +21,30 @@ TEST_CASE("algorithms")
{
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();
}));
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;
}));
}
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";
}));
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;
}));
}
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();
}));
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;
}));
}
@@ -61,8 +55,7 @@ TEST_CASE("algorithms")
{
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())
{
sum += static_cast<int>(value);
@@ -74,8 +67,7 @@ TEST_CASE("algorithms")
SECTION("writing")
{
auto add17 = [](json & value)
{
auto add17 = [](json& value) {
if (value.is_array())
{
value.push_back(17);
@@ -95,14 +87,12 @@ TEST_CASE("algorithms")
SECTION("std::count_if")
{
CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json & value)
{
return (value.is_number());
}) == 3);
CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json&)
{
return true;
}) == 9);
CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json& value) {
return (value.is_number());
}) == 3);
CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json&) {
return true;
}) == 9);
}
SECTION("std::mismatch")
@@ -127,9 +117,7 @@ TEST_CASE("algorithms")
// 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"};
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)
{
CHECK(std::equal(j_array.begin(), j_array.end(), j_array2.begin(), [](const json& a, const json& b) {
return (a.size() == b.size());
}));
}
@@ -143,9 +131,7 @@ TEST_CASE("algorithms")
SECTION("std::find_if")
{
auto it = std::find_if(j_array.begin(), j_array.end(),
[](const json & value)
{
auto it = std::find_if(j_array.begin(), j_array.end(), [](const json& value) {
return value.is_boolean();
});
CHECK(std::distance(j_array.begin(), it) == 4);
@@ -153,9 +139,7 @@ TEST_CASE("algorithms")
SECTION("std::find_if_not")
{
auto it = std::find_if_not(j_array.begin(), j_array.end(),
[](const json & value)
{
auto it = std::find_if_not(j_array.begin(), j_array.end(), [](const json& value) {
return value.is_number();
});
CHECK(std::distance(j_array.begin(), it) == 3);
@@ -164,11 +148,9 @@ TEST_CASE("algorithms")
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(),
[](const json & v1, const json & v2)
{
return v1.type() == v2.type();
}) == j_array.begin());
CHECK(std::adjacent_find(j_array.begin(), j_array.end(), [](const json& v1, const json& v2) {
return v1.type() == v2.type();
}) == j_array.begin());
}
}
@@ -188,8 +170,7 @@ TEST_CASE("algorithms")
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();
});
CHECK(std::distance(j_array.begin(), it) == 2);
@@ -211,8 +192,7 @@ TEST_CASE("algorithms")
SECTION("with user-defined comparison")
{
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();
});
CHECK(j == json({nullptr, 3, {{"one", 1}, {"two", 2}}, {1, 2, 3}}));
@@ -335,8 +315,7 @@ TEST_CASE("algorithms")
json dest_arr;
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;
});
CHECK(dest_arr == json({0, 3, 6, 9, 12, 15}));
@@ -349,7 +328,6 @@ TEST_CASE("algorithms")
std::copy_n(source_arr.begin(), numToCopy, std::back_inserter(dest_arr));
CHECK(dest_arr == json{0, 1});
}
SECTION("copy n chars")
{
@@ -361,5 +339,4 @@ TEST_CASE("algorithms")
CHECK(dest_arr == json{'1', '2', '3', '4'});
}
}
}
+44 -44
View File
@@ -12,8 +12,7 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
namespace
{
namespace {
// special test case to check if memory is leaked if constructor throws
template<class T>
struct bad_allocator : std::allocator<T>
@@ -21,21 +20,23 @@ struct bad_allocator : std::allocator<T>
using std::allocator<T>::allocator;
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>
void construct(T* /*unused*/, Args&& ... /*unused*/) // NOLINT(cppcoreguidelines-missing-std-forward)
void construct(T* /*unused*/, Args&&... /*unused*/) // NOLINT(cppcoreguidelines-missing-std-forward)
{
throw std::bad_alloc();
}
template <class U>
template<class U>
struct rebind
{
using other = bad_allocator<U>;
};
};
} // namespace
} // namespace
TEST_CASE("bad_alloc")
{
@@ -43,21 +44,20 @@ TEST_CASE("bad_alloc")
{
// create JSON type using the throwing allocator
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
CHECK_THROWS_AS(bad_json(bad_json::value_t::object), std::bad_alloc&);
}
}
namespace
{
namespace {
bool next_construct_fails = false;
bool next_destroy_fails = false;
bool next_deallocate_fails = false;
@@ -68,7 +68,7 @@ struct my_allocator : std::allocator<T>
using std::allocator<T>::allocator;
template<class... Args>
void construct(T* p, Args&& ... args)
void construct(T* p, Args&&... args)
{
if (next_construct_fails)
{
@@ -98,11 +98,11 @@ struct my_allocator : std::allocator<T>
throw std::bad_alloc();
}
static_cast<void>(p); // fix MSVC's C4100 warning
static_cast<void>(p); // fix MSVC's C4100 warning
p->~T();
}
template <class U>
template<class U>
struct rebind
{
using other = my_allocator<U>;
@@ -118,19 +118,19 @@ void my_allocator_clean_up(T* p)
alloc.destroy(p);
alloc.deallocate(p, 1);
}
} // namespace
} // namespace
TEST_CASE("controlled bad_alloc")
{
// create JSON type using the throwing allocator
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")
{
@@ -181,7 +181,7 @@ TEST_CASE("controlled bad_alloc")
SECTION("basic_json(const CompatibleObjectType&)")
{
next_construct_fails = false;
const std::map<std::string, std::string> v {{"foo", "bar"}};
const std::map<std::string, std::string> v{{"foo", "bar"}};
CHECK_NOTHROW(my_json(v));
next_construct_fails = true;
CHECK_THROWS_AS(my_json(v), std::bad_alloc&);
@@ -191,7 +191,7 @@ TEST_CASE("controlled bad_alloc")
SECTION("basic_json(const CompatibleArrayType&)")
{
next_construct_fails = false;
const std::vector<std::string> v {"foo", "bar", "baz"};
const std::vector<std::string> v{"foo", "bar", "baz"};
CHECK_NOTHROW(my_json(v));
next_construct_fails = true;
CHECK_THROWS_AS(my_json(v), std::bad_alloc&);
@@ -219,42 +219,42 @@ TEST_CASE("controlled bad_alloc")
}
}
namespace
{
namespace {
template<class T>
struct allocator_no_forward : std::allocator<T>
{
allocator_no_forward() = default;
template <class U>
allocator_no_forward(allocator_no_forward<U> /*unused*/) {}
template<class U>
allocator_no_forward(allocator_no_forward<U> /*unused*/)
{}
template <class U>
template<class U>
struct rebind
{
using other = allocator_no_forward<U>;
using other = allocator_no_forward<U>;
};
template <class... Args>
void construct(T* p, const Args& ... args) noexcept(noexcept(::new (static_cast<void*>(p)) T(args...)))
template<class... Args>
void construct(T* p, const Args&... args) noexcept(noexcept(::new(static_cast<void*>(p)) T(args...)))
{
// force copy even if move is available
::new (static_cast<void*>(p)) T(args...);
}
};
} // namespace
} // namespace
TEST_CASE("bad my_allocator::construct")
{
SECTION("my_allocator::construct doesn't forward")
{
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;
j["test"] = bad_alloc_json::array_t();
+36 -30
View File
@@ -30,13 +30,19 @@ class alt_string
static constexpr auto npos = static_cast<std::size_t>(-1);
alt_string(const char* str): str_impl(str) {}
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(const char* str)
: str_impl(str)
{}
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;
template <typename...TParams>
alt_string& append(TParams&& ...params)
template<typename... TParams>
alt_string& append(TParams&&... params)
{
str_impl.append(std::forward<TParams>(params)...);
return *this;
@@ -47,7 +53,7 @@ class alt_string
str_impl.push_back(c);
}
template <typename op_type>
template<typename op_type>
bool operator==(const op_type& op) const
{
return str_impl == op;
@@ -58,7 +64,7 @@ class alt_string
return str_impl == op.str_impl;
}
template <typename op_type>
template<typename op_type>
bool operator!=(const op_type& op) const
{
return str_impl != op;
@@ -74,17 +80,17 @@ class alt_string
return str_impl.size();
}
void resize (std::size_t n)
void resize(std::size_t n)
{
str_impl.resize(n);
}
void resize (std::size_t n, char c)
void resize(std::size_t n, char c)
{
str_impl.resize(n, c);
}
template <typename op_type>
template<typename op_type>
bool operator<(const op_type& op) const noexcept
{
return str_impl < op;
@@ -158,7 +164,7 @@ class alt_string
}
private:
std::string str_impl {};
std::string str_impl{};
friend bool operator<(const char* /*op1*/, const alt_string& /*op2*/) noexcept;
};
@@ -168,16 +174,16 @@ void int_to_string(alt_string& target, std::size_t value)
target = std::to_string(value).c_str();
}
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 >;
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>;
bool operator<(const char* op1, const alt_string& op2) noexcept
{
@@ -225,14 +231,14 @@ TEST_CASE("alternative string type")
{
alt_json doc;
doc["list"] = { 1, 0, 2 };
doc["list"] = {1, 0, 2};
alt_string dump = doc.dump();
CHECK(dump == R"({"list":[1,0,2]})");
}
{
alt_json doc;
doc["object"] = { {"currency", "USD"}, {"value", 42.99} };
doc["object"] = {{"currency", "USD"}, {"value", 42.99}};
alt_string dump = doc.dump();
CHECK(dump == R"({"object":{"currency":"USD","value":42.99}})");
}
@@ -259,11 +265,11 @@ TEST_CASE("alternative string type")
for (const auto& item : doc_array.items())
{
if (item.key() == "0" )
if (item.key() == "0")
{
CHECK( item.value() == "foo" );
CHECK(item.value() == "foo");
}
else if (item.key() == "1" )
else if (item.key() == "1")
{
CHECK(item.value() == "bar");
}
@@ -280,14 +286,14 @@ TEST_CASE("alternative string type")
doc["Who are you?"] = "I'm Batman";
CHECK("I'm Batman" == doc["Who are you?"]);
CHECK(doc["Who are you?"] == "I'm Batman");
CHECK(doc["Who are you?"] == "I'm Batman");
CHECK_FALSE("I'm Batman" != doc["Who are you?"]);
CHECK_FALSE(doc["Who are you?"] != "I'm Batman");
CHECK_FALSE(doc["Who are you?"] != "I'm Batman");
CHECK("I'm Bruce Wayne" != doc["Who are you?"]);
CHECK(doc["Who are you?"] != "I'm Bruce Wayne");
CHECK(doc["Who are you?"] != "I'm Bruce Wayne");
CHECK_FALSE("I'm Bruce Wayne" == doc["Who are you?"]);
CHECK_FALSE(doc["Who are you?"] == "I'm Bruce Wayne");
CHECK_FALSE(doc["Who are you?"] == "I'm Bruce Wayne");
{
const alt_json& const_doc = doc;
+5 -1
View File
@@ -18,7 +18,11 @@ DOCTEST_CLANG_SUPPRESS_WARNING("-Wstrict-overflow")
static int assert_counter;
/// 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>
using nlohmann::json;
+2 -2
View File
@@ -11,8 +11,8 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#include <fstream>
#include "make_test_data_available.hpp"
#include <fstream>
TEST_CASE("Binary Formats" * doctest::skip())
{
@@ -142,7 +142,7 @@ TEST_CASE("Binary Formats" * doctest::skip())
const auto bjdata_1_size = json::to_bjdata(j).size();
const auto bjdata_2_size = json::to_bjdata(j, true).size();
const auto bjdata_3_size = json::to_bjdata(j, true, true).size();
const auto bson_size = json::to_bson({{"", j}}).size(); // wrap array in object for BSON
const auto bson_size = json::to_bson({{"", j}}).size(); // wrap array in object for BSON
const auto cbor_size = json::to_cbor(j).size();
const auto msgpack_size = json::to_msgpack(j).size();
const auto ubjson_1_size = json::to_ubjson(j).size();
+887 -329
View File
File diff suppressed because it is too large Load Diff
+870 -399
View File
File diff suppressed because it is too large Load Diff
+30 -30
View File
@@ -18,7 +18,7 @@ TEST_CASE("capacity")
{
SECTION("boolean")
{
json j = true; // NOLINT(misc-const-correctness)
json j = true; // NOLINT(misc-const-correctness)
const json j_const = true;
SECTION("result of empty")
@@ -36,7 +36,7 @@ TEST_CASE("capacity")
SECTION("string")
{
json j = "hello world"; // NOLINT(misc-const-correctness)
json j = "hello world"; // NOLINT(misc-const-correctness)
const json j_const = "hello world";
SECTION("result of empty")
@@ -56,7 +56,7 @@ TEST_CASE("capacity")
{
SECTION("empty array")
{
json j = json::array(); // NOLINT(misc-const-correctness)
json j = json::array(); // NOLINT(misc-const-correctness)
const json j_const = json::array();
SECTION("result of empty")
@@ -74,7 +74,7 @@ TEST_CASE("capacity")
SECTION("filled array")
{
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
const json j_const = {1, 2, 3};
SECTION("result of empty")
@@ -95,7 +95,7 @@ TEST_CASE("capacity")
{
SECTION("empty object")
{
json j = json::object(); // NOLINT(misc-const-correctness)
json j = json::object(); // NOLINT(misc-const-correctness)
const json j_const = json::object();
SECTION("result of empty")
@@ -113,7 +113,7 @@ TEST_CASE("capacity")
SECTION("filled object")
{
json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness)
json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness)
const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}};
SECTION("result of empty")
@@ -132,7 +132,7 @@ TEST_CASE("capacity")
SECTION("number (integer)")
{
json j = -23; // NOLINT(misc-const-correctness)
json j = -23; // NOLINT(misc-const-correctness)
const json j_const = -23;
SECTION("result of empty")
@@ -150,7 +150,7 @@ TEST_CASE("capacity")
SECTION("number (unsigned)")
{
json j = 23u; // NOLINT(misc-const-correctness)
json j = 23u; // NOLINT(misc-const-correctness)
const json j_const = 23u;
SECTION("result of empty")
@@ -168,7 +168,7 @@ TEST_CASE("capacity")
SECTION("number (float)")
{
json j = 23.42; // NOLINT(misc-const-correctness)
json j = 23.42; // NOLINT(misc-const-correctness)
const json j_const = 23.42;
SECTION("result of empty")
@@ -186,7 +186,7 @@ TEST_CASE("capacity")
SECTION("null")
{
json j = nullptr; // NOLINT(misc-const-correctness)
json j = nullptr; // NOLINT(misc-const-correctness)
const json j_const = nullptr;
SECTION("result of empty")
@@ -207,7 +207,7 @@ TEST_CASE("capacity")
{
SECTION("boolean")
{
json j = true; // NOLINT(misc-const-correctness)
json j = true; // NOLINT(misc-const-correctness)
const json j_const = true;
SECTION("result of size")
@@ -227,7 +227,7 @@ TEST_CASE("capacity")
SECTION("string")
{
json j = "hello world"; // NOLINT(misc-const-correctness)
json j = "hello world"; // NOLINT(misc-const-correctness)
const json j_const = "hello world";
SECTION("result of size")
@@ -249,7 +249,7 @@ TEST_CASE("capacity")
{
SECTION("empty array")
{
json j = json::array(); // NOLINT(misc-const-correctness)
json j = json::array(); // NOLINT(misc-const-correctness)
const json j_const = json::array();
SECTION("result of size")
@@ -269,7 +269,7 @@ TEST_CASE("capacity")
SECTION("filled array")
{
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
const json j_const = {1, 2, 3};
SECTION("result of size")
@@ -292,7 +292,7 @@ TEST_CASE("capacity")
{
SECTION("empty object")
{
json j = json::object(); // NOLINT(misc-const-correctness)
json j = json::object(); // NOLINT(misc-const-correctness)
const json j_const = json::object();
SECTION("result of size")
@@ -312,7 +312,7 @@ TEST_CASE("capacity")
SECTION("filled object")
{
json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness)
json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness)
const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}};
SECTION("result of size")
@@ -333,7 +333,7 @@ TEST_CASE("capacity")
SECTION("number (integer)")
{
json j = -23; // NOLINT(misc-const-correctness)
json j = -23; // NOLINT(misc-const-correctness)
const json j_const = -23;
SECTION("result of size")
@@ -353,7 +353,7 @@ TEST_CASE("capacity")
SECTION("number (unsigned)")
{
json j = 23u; // NOLINT(misc-const-correctness)
json j = 23u; // NOLINT(misc-const-correctness)
const json j_const = 23u;
SECTION("result of size")
@@ -373,7 +373,7 @@ TEST_CASE("capacity")
SECTION("number (float)")
{
json j = 23.42; // NOLINT(misc-const-correctness)
json j = 23.42; // NOLINT(misc-const-correctness)
const json j_const = 23.42;
SECTION("result of size")
@@ -393,7 +393,7 @@ TEST_CASE("capacity")
SECTION("null")
{
json j = nullptr; // NOLINT(misc-const-correctness)
json j = nullptr; // NOLINT(misc-const-correctness)
const json j_const = nullptr;
SECTION("result of size")
@@ -416,7 +416,7 @@ TEST_CASE("capacity")
{
SECTION("boolean")
{
json j = true; // NOLINT(misc-const-correctness)
json j = true; // NOLINT(misc-const-correctness)
const json j_const = true;
SECTION("result of max_size")
@@ -428,7 +428,7 @@ TEST_CASE("capacity")
SECTION("string")
{
json j = "hello world"; // NOLINT(misc-const-correctness)
json j = "hello world"; // NOLINT(misc-const-correctness)
const json j_const = "hello world";
SECTION("result of max_size")
@@ -442,7 +442,7 @@ TEST_CASE("capacity")
{
SECTION("empty array")
{
json j = json::array(); // NOLINT(misc-const-correctness)
json j = json::array(); // NOLINT(misc-const-correctness)
const json j_const = json::array();
SECTION("result of max_size")
@@ -454,7 +454,7 @@ TEST_CASE("capacity")
SECTION("filled array")
{
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
const json j_const = {1, 2, 3};
SECTION("result of max_size")
@@ -469,7 +469,7 @@ TEST_CASE("capacity")
{
SECTION("empty object")
{
json j = json::object(); // NOLINT(misc-const-correctness)
json j = json::object(); // NOLINT(misc-const-correctness)
const json j_const = json::object();
SECTION("result of max_size")
@@ -481,7 +481,7 @@ TEST_CASE("capacity")
SECTION("filled object")
{
json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness)
json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness)
const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}};
SECTION("result of max_size")
@@ -494,7 +494,7 @@ TEST_CASE("capacity")
SECTION("number (integer)")
{
json j = -23; // NOLINT(misc-const-correctness)
json j = -23; // NOLINT(misc-const-correctness)
const json j_const = -23;
SECTION("result of max_size")
@@ -506,7 +506,7 @@ TEST_CASE("capacity")
SECTION("number (unsigned)")
{
json j = 23u; // NOLINT(misc-const-correctness)
json j = 23u; // NOLINT(misc-const-correctness)
const json j_const = 23u;
SECTION("result of max_size")
@@ -518,7 +518,7 @@ TEST_CASE("capacity")
SECTION("number (float)")
{
json j = 23.42; // NOLINT(misc-const-correctness)
json j = 23.42; // NOLINT(misc-const-correctness)
const json j_const = 23.42;
SECTION("result of max_size")
@@ -530,7 +530,7 @@ TEST_CASE("capacity")
SECTION("null")
{
json j = nullptr; // NOLINT(misc-const-correctness)
json j = nullptr; // NOLINT(misc-const-correctness)
const json j_const = nullptr;
SECTION("result of max_size")
+562 -427
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -49,7 +49,7 @@ TEST_CASE("const_iterator class")
{
SECTION("create from uninitialized iterator")
{
const json::iterator it {};
const json::iterator it{};
json::const_iterator const cit(it);
}
+6 -7
View File
@@ -387,18 +387,18 @@ TEST_CASE("iterator class")
SECTION("primitive_iterator_t")
{
using Iter = nlohmann::detail::primitive_iterator_t;
CHECK(std::is_same < decltype(std::declval<Iter&>()++), Iter >::value);
CHECK(std::is_same<decltype(std::declval<Iter&>()++), Iter>::value);
}
SECTION("iter_impl")
{
using Iter = nlohmann::detail::iter_impl<json>;
CHECK(std::is_same < decltype(std::declval<Iter&>()++), Iter >::value);
CHECK(std::is_same<decltype(std::declval<Iter&>()++), Iter>::value);
}
SECTION("json_reverse_iterator")
{
using Base = nlohmann::detail::iter_impl<json>;
using Iter = nlohmann::detail::json_reverse_iterator<Base>;
CHECK(std::is_same < decltype(std::declval<Iter&>()++), Iter >::value);
CHECK(std::is_same<decltype(std::declval<Iter&>()++), Iter>::value);
}
}
SECTION("post-decrement")
@@ -406,18 +406,18 @@ TEST_CASE("iterator class")
SECTION("primitive_iterator_t")
{
using Iter = nlohmann::detail::primitive_iterator_t;
CHECK(std::is_same < decltype(std::declval<Iter&>()--), Iter >::value);
CHECK(std::is_same<decltype(std::declval<Iter&>()--), Iter>::value);
}
SECTION("iter_impl")
{
using Iter = nlohmann::detail::iter_impl<json>;
CHECK(std::is_same < decltype(std::declval<Iter&>()--), Iter >::value );
CHECK(std::is_same<decltype(std::declval<Iter&>()--), Iter>::value);
}
SECTION("json_reverse_iterator")
{
using Base = nlohmann::detail::iter_impl<json>;
using Iter = nlohmann::detail::json_reverse_iterator<Base>;
CHECK(std::is_same < decltype(std::declval<Iter&>()--), Iter >::value );
CHECK(std::is_same<decltype(std::declval<Iter&>()--), Iter>::value);
}
}
}
@@ -462,7 +462,6 @@ TEST_CASE("iterator class")
using Iter = nlohmann::detail::json_reverse_iterator<Base>;
CHECK_FALSE(is_detected<can_post_decrement_temporary, Iter&>::value);
}
}
}
}
+4 -5
View File
@@ -12,22 +12,21 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
namespace
{
namespace {
// shortcut to scan a string literal
json::lexer::token_type scan_string(const char* s, bool ignore_comments = false);
json::lexer::token_type scan_string(const char* s, const bool ignore_comments)
{
auto ia = nlohmann::detail::input_adapter(s);
return nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments).scan(); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
return nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments).scan(); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
}
} // namespace
} // namespace
std::string get_error_message(const char* s, bool ignore_comments = false);
std::string get_error_message(const char* s, const bool ignore_comments)
{
auto ia = nlohmann::detail::input_adapter(s);
auto lexer = nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
auto lexer = nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
lexer.scan();
return lexer.get_error_message();
}
+181 -127
View File
@@ -12,13 +12,12 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#ifdef JSON_TEST_NO_GLOBAL_UDLS
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
#endif
#include <valarray>
namespace
{
namespace {
class SaxEventLogger
{
public:
@@ -124,14 +123,15 @@ class SaxEventLogger
return false;
}
std::vector<std::string> events {};
std::vector<std::string> events{};
bool errored = false;
};
class SaxCountdown : public nlohmann::json::json_sax_t
{
public:
explicit SaxCountdown(const int count) : events_left(count)
explicit SaxCountdown(const int count)
: events_left(count)
{}
bool null() override
@@ -249,8 +249,7 @@ bool accept_helper(const std::string& s)
CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept(false) == !el.errored);
// 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;
};
json const j_cb = json::parse(s, cb, false);
@@ -302,7 +301,7 @@ void comments_helper(const std::string& s)
}
}
} // namespace
} // namespace
TEST_CASE("parser class")
{
@@ -369,7 +368,7 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parser_helper("\uFF01"), json::parse_error&);
CHECK_THROWS_AS(parser_helper("[-4:1,]"), json::parse_error&);
// 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(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(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&);
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&);
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&);
@@ -592,39 +591,56 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parser_helper("+0"), json::parse_error&);
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::parse_error&);
"[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&);
CHECK_THROWS_WITH_AS(parser_helper("-01"),
"[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.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&);
CHECK_THROWS_WITH_AS(parser_helper("--1"),
"[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.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&);
CHECK_THROWS_WITH_AS(parser_helper("1."),
"[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.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&);
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&);
"[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 4: syntax error while parsing value - invalid number; expected digit after exponent sign; last read: '1E-'", json::parse_error&);
"[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&);
CHECK_THROWS_WITH_AS(parser_helper("1.E1"),
"[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&);
"[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&);
CHECK_THROWS_WITH_AS(parser_helper("-1E"),
"[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.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&);
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: '-0E#'", json::parse_error&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
}
}
}
@@ -692,7 +708,7 @@ TEST_CASE("parser class")
CHECK(accept_helper("\uFF01") == false);
CHECK(accept_helper("[-4:1,]") == false);
// unescaped control characters
CHECK(accept_helper("\"\x00\"") == false); // NOLINT(bugprone-string-literal-with-embedded-nul)
CHECK(accept_helper("\"\x00\"") == false); // NOLINT(bugprone-string-literal-with-embedded-nul)
CHECK(accept_helper("\"\x01\"") == false);
CHECK(accept_helper("\"\x02\"") == false);
CHECK(accept_helper("\"\x03\"") == false);
@@ -895,119 +911,170 @@ TEST_CASE("parser class")
{
// unexpected end of number
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 number; expected digit after '.'; last read: '0.'", json::parse_error&);
"[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&);
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::parse_error&);
"[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&);
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::parse_error&);
"[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&);
CHECK_THROWS_WITH_AS(parser_helper("-0."),
"[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.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&);
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::parse_error&);
"[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&);
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::parse_error&);
"[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&);
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 number; expected digit after '.'; last read: '0.:'", json::parse_error&);
"[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&);
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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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
CHECK_THROWS_WITH_AS(parser_helper("n"),
"[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&);
"[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&);
CHECK_THROWS_WITH_AS(parser_helper("nu"),
"[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.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'nu'",
json::parse_error&);
CHECK_THROWS_WITH_AS(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&);
"[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&);
"[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&);
"[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
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 literal; last read: 't'", json::parse_error&);
"[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&);
CHECK_THROWS_WITH_AS(parser_helper("tr"),
"[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.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'tr'",
json::parse_error&);
CHECK_THROWS_WITH_AS(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&);
"[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&);
"[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&);
"[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
CHECK_THROWS_WITH_AS(parser_helper("f"),
"[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&);
"[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&);
CHECK_THROWS_WITH_AS(parser_helper("fa"),
"[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.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid literal; last read: 'fa'",
json::parse_error&);
CHECK_THROWS_WITH_AS(parser_helper("fal"),
"[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&);
"[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&);
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&);
"[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&);
"[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&);
"[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
CHECK_THROWS_WITH_AS(parser_helper("["),
"[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&);
"[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&);
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::parse_error&);
"[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&);
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 end of input; expected '[', '{', or a literal", json::parse_error&);
"[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&);
"[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&);
"[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
CHECK_THROWS_WITH_AS(parser_helper("{"),
"[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&);
"[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&);
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::parse_error&);
"[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&);
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 end of input; expected '[', '{', or a literal", json::parse_error&);
"[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&);
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&);
"[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&);
"[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&);
"[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
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::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: '\"'",
json::parse_error&);
CHECK_THROWS_WITH_AS(parser_helper("\"\\\""),
"[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.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&);
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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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
for (int c = 1; c < 128; ++c)
@@ -1054,8 +1121,7 @@ TEST_CASE("parser class")
// invalid \uxxxx escapes
{
// check whether character is a valid hex character
const auto valid = [](int c)
{
const auto valid = [](int c) {
switch (c)
{
case ('0'):
@@ -1159,11 +1225,14 @@ TEST_CASE("parser class")
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
CHECK_THROWS_WITH_AS(_ = json::parse("\"\\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\\uD80C'", json::parse_error&);
"[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&);
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\\u0000'", json::parse_error&);
"[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&);
"[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)")
@@ -1269,8 +1338,7 @@ TEST_CASE("parser class")
// invalid \uxxxx escapes
{
// check whether character is a valid hex character
const auto valid = [](int c)
{
const auto valid = [](int c) {
switch (c)
{
case ('0'):
@@ -1361,8 +1429,7 @@ TEST_CASE("parser class")
// 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;
};
@@ -1400,77 +1467,69 @@ TEST_CASE("parser class")
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;
});
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;
});
CHECK (j_array == json({1, 2, {3, 4, 5}, 4, 5}));
CHECK(j_array == json({1, 2, {3, 4, 5}, 4, 5}));
}
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;
});
// 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;
});
// the top-level array will be discarded, leaving a null
CHECK (j_array.is_null());
CHECK(j_array.is_null());
}
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
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);
});
CHECK (j_array == json({1, {3, 4, 5}, 4, 5}));
CHECK(j_array == json({1, {3, 4, 5}, 4, 5}));
}
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"));
});
// the specified object will be discarded, and removed.
CHECK (j_filtered1.size() == 2);
CHECK (j_filtered1 == json({1, {{"qux", "baz"}}}));
CHECK(j_filtered1.size() == 2);
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;
});
// removed all objects in array.
CHECK (j_filtered2.size() == 1);
CHECK (j_filtered2 == json({1}));
CHECK(j_filtered2.size() == 1);
CHECK(j_filtered2 == json({1}));
}
SECTION("filter specific events")
@@ -1478,8 +1537,7 @@ TEST_CASE("parser class")
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;
if (e == json::parse_event_t::object_end && first)
{
@@ -1491,12 +1549,11 @@ TEST_CASE("parser class")
});
// the first completed object will be discarded
CHECK (j_object == json({{"foo", 2}}));
CHECK(j_object == json({{"foo", 2}}));
}
{
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;
if (e == json::parse_event_t::array_end && first)
{
@@ -1508,7 +1565,7 @@ TEST_CASE("parser class")
});
// the first completed array will be discarded
CHECK (j_array == json({1, 2, 4, 5}));
CHECK(j_array == json({1, 2, 4, 5}));
}
}
}
@@ -1519,14 +1576,12 @@ TEST_CASE("parser class")
// object and array is discarded only after the closing character
// 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;
});
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;
});
CHECK(j_empty_array == json());
@@ -1545,7 +1600,7 @@ TEST_CASE("parser class")
SECTION("from std::array")
{
std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };
std::array<uint8_t, 5> v{{'t', 'r', 'u', 'e'}};
json j;
json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);
CHECK(j == json(true));
@@ -1553,7 +1608,7 @@ TEST_CASE("parser class")
SECTION("from array")
{
uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
json j;
json::parser(nlohmann::detail::input_adapter(std::begin(v), std::end(v))).parse(true, j);
CHECK(j == json(true));
@@ -1593,8 +1648,7 @@ TEST_CASE("parser class")
{
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;
};
+199 -192
View File
@@ -21,9 +21,9 @@ using nlohmann::json;
#if JSON_HAS_THREE_WAY_COMPARISON
// this can be replaced with the doctest stl extension header in version 2.5
namespace doctest
{
template<> struct StringMaker<std::partial_ordering>
namespace doctest {
template<>
struct StringMaker<std::partial_ordering>
{
static String convert(const std::partial_ordering& order)
{
@@ -46,20 +46,19 @@ template<> struct StringMaker<std::partial_ordering>
return "{?}";
}
};
} // namespace doctest
} // namespace doctest
#endif
namespace
{
namespace {
// helper function to check std::less<json::value_t>
// see https://en.cppreference.com/w/cpp/utility/functional/less
template <typename A, typename B, typename U = std::less<json::value_t>>
template<typename A, typename B, typename U = std::less<json::value_t>>
bool f(A a, B b, U u = U())
{
return u(a, b);
}
} // namespace
} // namespace
TEST_CASE("lexicographical comparison operators")
{
@@ -87,33 +86,32 @@ TEST_CASE("lexicographical comparison operators")
SECTION("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::object,
json::value_t::array,
json::value_t::string,
json::value_t::binary,
json::value_t::discarded
};
{
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::object,
json::value_t::array,
json::value_t::string,
json::value_t::binary,
json::value_t::discarded};
std::vector<std::vector<bool>> expected_lt =
{
//0 1 2 3 4 5 6 7 8 9
{f_, _t, _t, _t, _t, _t, _t, _t, _t, f_}, // 0
{f_, f_, _t, _t, _t, _t, _t, _t, _t, f_}, // 1
{f_, f_, f_, f_, f_, _t, _t, _t, _t, f_}, // 2
{f_, f_, f_, f_, f_, _t, _t, _t, _t, f_}, // 3
{f_, f_, f_, f_, f_, _t, _t, _t, _t, f_}, // 4
{f_, f_, f_, f_, f_, f_, _t, _t, _t, f_}, // 5
{f_, f_, f_, f_, f_, f_, f_, _t, _t, f_}, // 6
{f_, f_, f_, f_, f_, f_, f_, f_, _t, f_}, // 7
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 8
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 9
};
{
//0 1 2 3 4 5 6 7 8 9
{f_, _t, _t, _t, _t, _t, _t, _t, _t, f_}, // 0
{f_, f_, _t, _t, _t, _t, _t, _t, _t, f_}, // 1
{f_, f_, f_, f_, f_, _t, _t, _t, _t, f_}, // 2
{f_, f_, f_, f_, f_, _t, _t, _t, _t, f_}, // 3
{f_, f_, f_, f_, f_, _t, _t, _t, _t, f_}, // 4
{f_, f_, f_, f_, f_, f_, _t, _t, _t, f_}, // 5
{f_, f_, f_, f_, f_, f_, f_, _t, _t, f_}, // 6
{f_, f_, f_, f_, f_, f_, f_, f_, _t, f_}, // 7
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 8
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 9
};
SECTION("comparison: less")
{
@@ -141,19 +139,19 @@ TEST_CASE("lexicographical comparison operators")
SECTION("comparison: 3-way")
{
std::vector<std::vector<std::partial_ordering>> expected =
{
//0 1 2 3 4 5 6 7 8 9
{eq, lt, lt, lt, lt, lt, lt, lt, lt, un}, // 0
{gt, eq, lt, lt, lt, lt, lt, lt, lt, un}, // 1
{gt, gt, eq, eq, eq, lt, lt, lt, lt, un}, // 2
{gt, gt, eq, eq, eq, lt, lt, lt, lt, un}, // 3
{gt, gt, eq, eq, eq, lt, lt, lt, lt, un}, // 4
{gt, gt, gt, gt, gt, eq, lt, lt, lt, un}, // 5
{gt, gt, gt, gt, gt, gt, eq, lt, lt, un}, // 6
{gt, gt, gt, gt, gt, gt, gt, eq, lt, un}, // 7
{gt, gt, gt, gt, gt, gt, gt, gt, eq, un}, // 8
{un, un, un, un, un, un, un, un, un, un}, // 9
};
{
//0 1 2 3 4 5 6 7 8 9
{eq, lt, lt, lt, lt, lt, lt, lt, lt, un}, // 0
{gt, eq, lt, lt, lt, lt, lt, lt, lt, un}, // 1
{gt, gt, eq, eq, eq, lt, lt, lt, lt, un}, // 2
{gt, gt, eq, eq, eq, lt, lt, lt, lt, un}, // 3
{gt, gt, eq, eq, eq, lt, lt, lt, lt, un}, // 4
{gt, gt, gt, gt, gt, eq, lt, lt, lt, un}, // 5
{gt, gt, gt, gt, gt, gt, eq, lt, lt, un}, // 6
{gt, gt, gt, gt, gt, gt, gt, eq, lt, un}, // 7
{gt, gt, gt, gt, gt, gt, gt, gt, eq, un}, // 8
{un, un, un, un, un, un, un, un, un, un}, // 9
};
// check expected partial_ordering against expected boolean
REQUIRE(expected.size() == expected_lt.size());
@@ -177,7 +175,7 @@ TEST_CASE("lexicographical comparison operators")
{
CAPTURE(i)
CAPTURE(j)
CHECK((j_types[i] <=> j_types[j]) == expected[i][j]); // *NOPAD*
CHECK((j_types[i] <= > j_types[j]) == expected[i][j]); // *NOPAD*
}
}
}
@@ -187,102 +185,113 @@ TEST_CASE("lexicographical comparison operators")
SECTION("values")
{
json j_values =
{
nullptr, nullptr, // 0 1
-17, 42, // 2 3
8u, 13u, // 4 5
3.14159, 23.42, // 6 7
nan, nan, // 8 9
"foo", "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
};
{
nullptr,
nullptr, // 0 1
-17,
42, // 2 3
8u,
13u, // 4 5
3.14159,
23.42, // 6 7
nan,
nan, // 8 9
"foo",
"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 =
{
//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_}, // 1
{f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 2
{f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 3
{f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 4
{f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 5
{f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 6
{f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 7
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 8
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 9
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 10
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 11
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 12
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_}, // 13
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_}, // 14
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_}, // 15
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_}, // 16
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_}, // 17
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_}, // 18
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_}, // 19
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 20
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 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_}, // 1
{f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 2
{f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 3
{f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 4
{f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 5
{f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 6
{f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 7
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 8
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 9
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 10
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 11
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 12
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_}, // 13
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_}, // 14
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_}, // 15
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_}, // 16
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_}, // 17
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_}, // 18
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_}, // 19
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 20
{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 =
{
//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_}, // 1
{f_, f_, f_, _t, _t, _t, _t, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 2
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 3
{f_, f_, f_, _t, f_, _t, f_, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 4
{f_, f_, f_, _t, f_, f_, f_, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 5
{f_, f_, f_, _t, _t, _t, f_, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 6
{f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 7
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 8
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 9
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_}, // 10
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_}, // 11
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 12
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 13
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, _t, f_, f_, _t, _t, f_, f_}, // 14
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_}, // 15
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, f_, f_, _t, _t, f_, f_}, // 16
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, f_, _t, _t, f_, f_}, // 17
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_}, // 18
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 19
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 20
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 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_}, // 1
{f_, f_, f_, _t, _t, _t, _t, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 2
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 3
{f_, f_, f_, _t, f_, _t, f_, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 4
{f_, f_, f_, _t, f_, f_, f_, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 5
{f_, f_, f_, _t, _t, _t, f_, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 6
{f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 7
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 8
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 9
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_}, // 10
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_}, // 11
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 12
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 13
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, _t, f_, f_, _t, _t, f_, f_}, // 14
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_}, // 15
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, f_, f_, _t, _t, f_, f_}, // 16
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, f_, _t, _t, f_, f_}, // 17
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_}, // 18
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 19
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 20
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 21
};
SECTION("compares unordered")
{
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
{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_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 2
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 3
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 4
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 5
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 6
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 7
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 8
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 9
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 10
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 11
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 12
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 13
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 14
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 15
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 16
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 17
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 18
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 19
{_t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t}, // 20
{_t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t}, // 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}, // 1
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 2
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 3
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 4
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 5
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 6
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 7
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 8
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 9
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 10
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 11
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 12
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 13
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 14
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 15
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 16
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 17
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 18
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 19
{_t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t}, // 20
{_t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t}, // 21
};
// check if two values compare unordered as expected
REQUIRE(expected.size() == j_values.size());
@@ -302,31 +311,31 @@ TEST_CASE("lexicographical comparison operators")
SECTION("compares unordered (inverse)")
{
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
{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_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 2
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 3
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 4
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 5
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 6
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 7
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 8
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 9
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 10
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 11
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 12
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 13
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 14
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 15
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 16
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 17
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 18
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 19
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 20
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 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_}, // 1
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 2
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 3
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 4
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 5
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 6
{f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 7
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 8
{f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 9
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 10
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 11
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 12
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 13
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 14
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 15
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 16
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 17
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 18
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 19
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 20
{f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 21
};
// check that two values compare unordered as expected (with legacy-mode enabled)
REQUIRE(expected.size() == j_values.size());
@@ -497,31 +506,31 @@ TEST_CASE("lexicographical comparison operators")
SECTION("comparison: 3-way")
{
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
{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
{gt, gt, eq, lt, lt, lt, lt, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 2
{gt, gt, gt, eq, gt, gt, gt, gt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 3
{gt, gt, gt, lt, eq, lt, gt, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 4
{gt, gt, gt, lt, gt, eq, gt, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 5
{gt, gt, gt, lt, lt, lt, eq, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 6
{gt, gt, gt, lt, gt, gt, gt, eq, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 7
{gt, gt, un, un, un, un, un, un, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 8
{gt, gt, un, un, un, un, un, un, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 9
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, eq, gt, gt, gt, gt, gt, gt, gt, lt, lt, un, un}, // 10
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, eq, gt, gt, gt, gt, gt, gt, lt, lt, un, un}, // 11
{gt, gt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, eq, gt, lt, lt, lt, lt, lt, lt, un, un}, // 12
{gt, gt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, eq, lt, lt, lt, lt, lt, lt, un, un}, // 13
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, eq, lt, gt, gt, lt, lt, un, un}, // 14
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, gt, eq, gt, gt, lt, lt, un, un}, // 15
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, lt, lt, eq, gt, lt, lt, un, un}, // 16
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, lt, lt, lt, eq, lt, lt, un, un}, // 17
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, eq, lt, un, un}, // 18
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, eq, un, un}, // 19
{un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un}, // 20
{un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un}, // 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}, // 1
{gt, gt, eq, lt, lt, lt, lt, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 2
{gt, gt, gt, eq, gt, gt, gt, gt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 3
{gt, gt, gt, lt, eq, lt, gt, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 4
{gt, gt, gt, lt, gt, eq, gt, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 5
{gt, gt, gt, lt, lt, lt, eq, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 6
{gt, gt, gt, lt, gt, gt, gt, eq, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 7
{gt, gt, un, un, un, un, un, un, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 8
{gt, gt, un, un, un, un, un, un, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 9
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, eq, gt, gt, gt, gt, gt, gt, gt, lt, lt, un, un}, // 10
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, eq, gt, gt, gt, gt, gt, gt, lt, lt, un, un}, // 11
{gt, gt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, eq, gt, lt, lt, lt, lt, lt, lt, un, un}, // 12
{gt, gt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, eq, lt, lt, lt, lt, lt, lt, un, un}, // 13
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, eq, lt, gt, gt, lt, lt, un, un}, // 14
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, gt, eq, gt, gt, lt, lt, un, un}, // 15
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, lt, lt, eq, gt, lt, lt, un, un}, // 16
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, lt, lt, lt, eq, lt, lt, un, un}, // 17
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, eq, lt, un, un}, // 18
{gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, eq, un, un}, // 19
{un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un}, // 20
{un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un}, // 21
};
// check expected partial_ordering against expected booleans
REQUIRE(expected.size() == expected_eq.size());
@@ -552,7 +561,7 @@ TEST_CASE("lexicographical comparison operators")
{
CAPTURE(i)
CAPTURE(j)
CHECK((j_values[i] <=> j_values[j]) == expected[i][j]); // *NOPAD*
CHECK((j_values[i] <= > j_values[j]) == expected[i][j]); // *NOPAD*
}
}
}
@@ -576,20 +585,18 @@ TEST_CASE("lexicographical comparison operators")
[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
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);
});
CHECK (j_array == json({1, {3, 4, 5}, 4, 5}));
CHECK(j_array == json({1, {3, 4, 5}, 4, 5}));
}
}
#endif
+2 -2
View File
@@ -130,7 +130,7 @@ TEST_CASE("concepts")
SECTION("Swappable")
{
{
json j {1, 2, 3};
json j{1, 2, 3};
json::iterator it1 = j.begin();
json::iterator it2 = j.end();
swap(it1, it2);
@@ -138,7 +138,7 @@ TEST_CASE("concepts")
CHECK(it2 == j.begin());
}
{
json j {1, 2, 3};
json j{1, 2, 3};
json::const_iterator it1 = j.cbegin();
json::const_iterator it2 = j.cend();
swap(it1, it2);
+56 -58
View File
@@ -131,7 +131,7 @@ TEST_CASE("constructors")
SECTION("filled object")
{
json::object_t const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
json::object_t const o{{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
json const j(o);
CHECK(j.type() == json::value_t::object);
}
@@ -140,12 +140,12 @@ TEST_CASE("constructors")
SECTION("create an object (implicit)")
{
// 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);
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);
CHECK(j.type() == json::value_t::object);
CHECK(j == j_reference);
@@ -153,8 +153,7 @@ TEST_CASE("constructors")
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"},
{"c", "d"},
{"e", "f"},
@@ -166,7 +165,7 @@ TEST_CASE("constructors")
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);
CHECK(j.type() == json::value_t::object);
CHECK(j == j_reference);
@@ -174,7 +173,7 @@ TEST_CASE("constructors")
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);
CHECK(j.type() == json::value_t::object);
CHECK(j == j_reference);
@@ -182,7 +181,7 @@ TEST_CASE("constructors")
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);
CHECK(j.type() == json::value_t::object);
CHECK(j == j_reference);
@@ -190,7 +189,7 @@ TEST_CASE("constructors")
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);
CHECK(j.type() == json::value_t::object);
CHECK(j == j_reference);
@@ -215,7 +214,7 @@ TEST_CASE("constructors")
SECTION("filled array")
{
json::array_t const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
json::array_t const a{json(1), json(1u), json(2.2), json(false), json("string"), json()};
json const j(a);
CHECK(j.type() == json::value_t::array);
}
@@ -224,12 +223,12 @@ TEST_CASE("constructors")
SECTION("create an array (implicit)")
{
// reference array
json::array_t const a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()};
json::array_t const a_reference{json(1), json(1u), json(2.2), json(false), json("string"), json()};
json const j_reference(a_reference);
SECTION("std::list<json>")
{
std::list<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
std::list<json> const a{json(1), json(1u), json(2.2), json(false), json("string"), json()};
json const j(a);
CHECK(j.type() == json::value_t::array);
CHECK(j == j_reference);
@@ -258,7 +257,7 @@ TEST_CASE("constructors")
SECTION("std::tuple")
{
const auto t = std::make_tuple(1.0, std::string{"string"}, 42, std::vector<int> {0, 1});
const auto t = std::make_tuple(1.0, std::string{"string"}, 42, std::vector<int>{0, 1});
json const j(t);
CHECK(j.type() == json::value_t::array);
@@ -292,7 +291,7 @@ TEST_CASE("constructors")
SECTION("std::forward_list<json>")
{
std::forward_list<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
std::forward_list<json> const a{json(1), json(1u), json(2.2), json(false), json("string"), json()};
json const j(a);
CHECK(j.type() == json::value_t::array);
CHECK(j == j_reference);
@@ -300,7 +299,7 @@ TEST_CASE("constructors")
SECTION("std::array<json, 6>")
{
std::array<json, 6> const a {{json(1), json(1u), json(2.2), json(false), json("string"), json()}};
std::array<json, 6> const a{{json(1), json(1u), json(2.2), json(false), json("string"), json()}};
json const j(a);
CHECK(j.type() == json::value_t::array);
CHECK(j == j_reference);
@@ -341,7 +340,7 @@ TEST_CASE("constructors")
SECTION("std::vector<json>")
{
std::vector<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
std::vector<json> const a{json(1), json(1u), json(2.2), json(false), json("string"), json()};
json const j(a);
CHECK(j.type() == json::value_t::array);
CHECK(j == j_reference);
@@ -349,7 +348,7 @@ TEST_CASE("constructors")
SECTION("std::deque<json>")
{
std::deque<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
std::deque<json> const a{json(1), json(1u), json(2.2), json(false), json("string"), json()};
json const j(a);
CHECK(j.type() == json::value_t::array);
CHECK(j == j_reference);
@@ -357,7 +356,7 @@ TEST_CASE("constructors")
SECTION("std::set<json>")
{
std::set<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
std::set<json> const a{json(1), json(1u), json(2.2), json(false), json("string"), json()};
json const j(a);
CHECK(j.type() == json::value_t::array);
// we cannot really check for equality here
@@ -365,7 +364,7 @@ TEST_CASE("constructors")
SECTION("std::unordered_set<json>")
{
std::unordered_set<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
std::unordered_set<json> const a{json(1), json(1u), json(2.2), json(false), json("string"), json()};
json const j(a);
CHECK(j.type() == json::value_t::array);
// we cannot really check for equality here
@@ -390,7 +389,7 @@ TEST_CASE("constructors")
SECTION("filled string")
{
json::string_t const s {"Hello world"};
json::string_t const s{"Hello world"};
json const j(s);
CHECK(j.type() == json::value_t::string);
}
@@ -399,12 +398,12 @@ TEST_CASE("constructors")
SECTION("create a string (implicit)")
{
// reference string
json::string_t const s_reference {"Hello world"};
json::string_t const s_reference{"Hello world"};
json const j_reference(s_reference);
SECTION("std::string")
{
std::string const s {"Hello world"};
std::string const s{"Hello world"};
json const j(s);
CHECK(j.type() == json::value_t::string);
CHECK(j == j_reference);
@@ -412,7 +411,7 @@ TEST_CASE("constructors")
SECTION("char[]")
{
char const s[] {"Hello world"}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
char const s[]{"Hello world"}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
json const j(s);
CHECK(j.type() == json::value_t::string);
CHECK(j == j_reference);
@@ -420,7 +419,7 @@ TEST_CASE("constructors")
SECTION("const char*")
{
const char* s {"Hello world"};
const char* s{"Hello world"};
json const j(s);
CHECK(j.type() == json::value_t::string);
CHECK(j == j_reference);
@@ -918,13 +917,13 @@ TEST_CASE("constructors")
{
SECTION("explicit")
{
json const j(json::initializer_list_t {});
json const j(json::initializer_list_t{});
CHECK(j.type() == json::value_t::object);
}
SECTION("implicit")
{
json const j {};
json const j{};
CHECK(j.type() == json::value_t::null);
}
}
@@ -935,13 +934,13 @@ TEST_CASE("constructors")
{
SECTION("explicit")
{
json const j(json::initializer_list_t {json(json::array_t())});
json const j(json::initializer_list_t{json(json::array_t())});
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json const j {json::array_t()};
json const j{json::array_t()};
CHECK(j.type() == json::value_t::array);
}
}
@@ -950,13 +949,13 @@ TEST_CASE("constructors")
{
SECTION("explicit")
{
json const j(json::initializer_list_t {json(json::object_t())});
json const j(json::initializer_list_t{json(json::object_t())});
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json const j {json::object_t()};
json const j{json::object_t()};
CHECK(j.type() == json::value_t::array);
}
}
@@ -965,13 +964,13 @@ TEST_CASE("constructors")
{
SECTION("explicit")
{
json const j(json::initializer_list_t {json("Hello world")});
json const j(json::initializer_list_t{json("Hello world")});
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json const j {"Hello world"};
json const j{"Hello world"};
CHECK(j.type() == json::value_t::array);
}
}
@@ -980,13 +979,13 @@ TEST_CASE("constructors")
{
SECTION("explicit")
{
json const j(json::initializer_list_t {json(true)});
json const j(json::initializer_list_t{json(true)});
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json const j {true};
json const j{true};
CHECK(j.type() == json::value_t::array);
}
}
@@ -995,13 +994,13 @@ TEST_CASE("constructors")
{
SECTION("explicit")
{
json const j(json::initializer_list_t {json(1)});
json const j(json::initializer_list_t{json(1)});
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json const j {1};
json const j{1};
CHECK(j.type() == json::value_t::array);
}
}
@@ -1010,13 +1009,13 @@ TEST_CASE("constructors")
{
SECTION("explicit")
{
json const j(json::initializer_list_t {json(1u)});
json const j(json::initializer_list_t{json(1u)});
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json const j {1u};
json const j{1u};
CHECK(j.type() == json::value_t::array);
}
}
@@ -1025,13 +1024,13 @@ TEST_CASE("constructors")
{
SECTION("explicit")
{
json const j(json::initializer_list_t {json(42.23)});
json const j(json::initializer_list_t{json(42.23)});
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json const j {42.23};
json const j{42.23};
CHECK(j.type() == json::value_t::array);
}
}
@@ -1041,13 +1040,13 @@ TEST_CASE("constructors")
{
SECTION("explicit")
{
json const j(json::initializer_list_t {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()});
json const j(json::initializer_list_t{1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()});
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json const j {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()};
json const j{1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()};
CHECK(j.type() == json::value_t::array);
}
}
@@ -1056,13 +1055,13 @@ TEST_CASE("constructors")
{
SECTION("object")
{
json const j { {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} };
json const j{{"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}};
CHECK(j.type() == json::value_t::object);
}
SECTION("array")
{
json const j { {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 };
json const j{{"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13};
CHECK(j.type() == json::value_t::array);
}
}
@@ -1077,14 +1076,14 @@ TEST_CASE("constructors")
SECTION("object")
{
json const j = json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} });
json const j = json::object({{"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}});
CHECK(j.type() == json::value_t::object);
}
SECTION("object with error")
{
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")
@@ -1095,7 +1094,7 @@ TEST_CASE("constructors")
SECTION("array")
{
json const j = json::array({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} });
json const j = json::array({{"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}});
CHECK(j.type() == json::value_t::array);
}
}
@@ -1144,7 +1143,7 @@ TEST_CASE("constructors")
{
json::array_t source = {1, 2, 3};
const auto* source_addr = source.data();
json j {std::move(source)};
json j{std::move(source)};
const auto* target_addr = j[0].get_ref<json::array_t const&>().data();
const bool success = (target_addr == source_addr);
CHECK(success);
@@ -1154,7 +1153,7 @@ TEST_CASE("constructors")
{
json::array_t source = {1, 2, 3};
const auto* source_addr = source.data();
json const j {{"key", std::move(source)}};
json const j{{"key", std::move(source)}};
const auto* target_addr = j["key"].get_ref<json::array_t const&>().data();
const bool success = (target_addr == source_addr);
CHECK(success);
@@ -1187,7 +1186,7 @@ TEST_CASE("constructors")
{
json::object_t source = {{"hello", "world"}};
const json* source_addr = &source.at("hello");
json j {std::move(source)};
json j{std::move(source)};
CHECK(&(j[0].get_ref<json::object_t const&>().at("hello")) == source_addr);
}
@@ -1195,7 +1194,7 @@ TEST_CASE("constructors")
{
json::object_t source = {{"hello", "world"}};
const json* source_addr = &source.at("hello");
json j {{"key", std::move(source)}};
json j{{"key", std::move(source)}};
CHECK(&(j["key"].get_ref<json::object_t const&>().at("hello")) == source_addr);
}
@@ -1220,23 +1219,23 @@ TEST_CASE("constructors")
{
SECTION("constructor with implicit types (array)")
{
json source {1, 2, 3};
json source{1, 2, 3};
const json* source_addr = &source[0];
json j {std::move(source), {}};
json j{std::move(source), {}};
CHECK(&j[0][0] == source_addr);
}
SECTION("constructor with implicit types (object)")
{
json source {1, 2, 3};
json source{1, 2, 3};
const json* source_addr = &source[0];
json j {{"key", std::move(source)}};
json j{{"key", std::move(source)}};
CHECK(&j["key"][0] == source_addr);
}
SECTION("assignment with implicit types (array)")
{
json source {1, 2, 3};
json source{1, 2, 3};
const json* source_addr = &source[0];
json j = {std::move(source), {}};
CHECK(&j[0][0] == source_addr);
@@ -1244,13 +1243,12 @@ TEST_CASE("constructors")
SECTION("assignment with implicit types (object)")
{
json source {1, 2, 3};
json source{1, 2, 3};
const json* source_addr = &source[0];
json j = {{"key", std::move(source)}};
CHECK(&j["key"][0] == source_addr);
}
}
}
}
+21 -21
View File
@@ -17,82 +17,82 @@ TEST_CASE("other constructors and destructor")
{
SECTION("object")
{
json j {{"foo", 1}, {"bar", false}};
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
json j{{"foo", 1}, {"bar", false}};
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("array")
{
json j {"foo", 1, 42.23, false};
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
json j{"foo", 1, 42.23, false};
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("null")
{
json j(nullptr);
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("boolean")
{
json j(true);
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("string")
{
json j("Hello world");
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("number (integer)")
{
json j(42);
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("number (unsigned)")
{
json j(42u);
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("number (floating-point)")
{
json j(42.23);
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("binary")
{
json j = json::binary({1, 2, 3});
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
}
SECTION("move constructor")
{
json j {{"foo", "bar"}, {"baz", {1, 2, 3, 4}}, {"a", 42u}, {"b", 42.23}, {"c", nullptr}};
json j{{"foo", "bar"}, {"baz", {1, 2, 3, 4}}, {"a", 42u}, {"b", 42.23}, {"c", nullptr}};
CHECK(j.type() == json::value_t::object);
const json k(std::move(j));
CHECK(k.type() == json::value_t::object);
CHECK(j.type() == json::value_t::null); // NOLINT: access after move is OK here
CHECK(j.type() == json::value_t::null); // NOLINT: access after move is OK here
}
SECTION("copy assignment")
{
SECTION("object")
{
json j {{"foo", 1}, {"bar", false}};
json j{{"foo", 1}, {"bar", false}};
json k;
k = j;
CHECK(j == k);
@@ -100,7 +100,7 @@ TEST_CASE("other constructors and destructor")
SECTION("array")
{
json j {"foo", 1, 42.23, false};
json j{"foo", 1, 42.23, false};
json k;
k = j;
CHECK(j == k);
@@ -167,20 +167,20 @@ TEST_CASE("other constructors and destructor")
{
SECTION("object")
{
auto* j = new json {{"foo", 1}, {"bar", false}}; // NOLINT(cppcoreguidelines-owning-memory)
delete j; // NOLINT(cppcoreguidelines-owning-memory)
auto* j = new json{{"foo", 1}, {"bar", false}}; // NOLINT(cppcoreguidelines-owning-memory)
delete j; // NOLINT(cppcoreguidelines-owning-memory)
}
SECTION("array")
{
auto* j = new json {"foo", 1, 1u, false, 23.42}; // NOLINT(cppcoreguidelines-owning-memory)
delete j; // NOLINT(cppcoreguidelines-owning-memory)
auto* j = new json{"foo", 1, 1u, false, 23.42}; // NOLINT(cppcoreguidelines-owning-memory)
delete j; // NOLINT(cppcoreguidelines-owning-memory)
}
SECTION("string")
{
auto* j = new json("Hello world"); // NOLINT(cppcoreguidelines-owning-memory)
delete j; // NOLINT(cppcoreguidelines-owning-memory)
auto* j = new json("Hello world"); // NOLINT(cppcoreguidelines-owning-memory)
delete j; // NOLINT(cppcoreguidelines-owning-memory)
}
}
}
+4 -5
View File
@@ -14,13 +14,12 @@ using nlohmann::json;
#include <sstream>
namespace
{
namespace {
struct alt_string_iter
{
alt_string_iter() = default;
alt_string_iter(const char* cstr)
: impl(cstr)
: impl(cstr)
{}
void reserve(std::size_t s)
@@ -62,7 +61,7 @@ struct alt_string_data
{
alt_string_data() = default;
alt_string_data(const char* cstr)
: impl(cstr)
: impl(cstr)
{}
void reserve(std::size_t s)
@@ -102,7 +101,7 @@ void check_escaped(const char* original, const char* escaped, const bool ensure_
s.dump_escaped(original, ensure_ascii);
CHECK(ss.str() == escaped);
}
} // namespace
} // namespace
TEST_CASE("convenience functions")
{
+186 -113
View File
@@ -37,12 +37,11 @@ TEST_CASE("value conversion")
SECTION("get an object (explicit)")
{
const json::object_t o_reference = {{"object", json::object()},
{"array", {1, 2, 3, 4}},
{"number", 42},
{"boolean", false},
{"null", nullptr},
{"string", "Hello world"}
};
{"array", {1, 2, 3, 4}},
{"number", 42},
{"boolean", false},
{"null", nullptr},
{"string", "Hello world"}};
json j(o_reference);
SECTION("json::object_t")
@@ -83,37 +82,43 @@ TEST_CASE("value conversion")
{
CHECK_THROWS_WITH_AS(
json(json::value_t::null).get<json::object_t>(),
"[json.exception.type_error.302] type must be object, but is null", json::type_error&);
"[json.exception.type_error.302] type must be object, but is null",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::array).get<json::object_t>(),
"[json.exception.type_error.302] type must be object, but is array", json::type_error&);
"[json.exception.type_error.302] type must be object, but is array",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::string).get<json::object_t>(),
"[json.exception.type_error.302] type must be object, but is string", json::type_error&);
"[json.exception.type_error.302] type must be object, but is string",
json::type_error&);
CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<json::object_t>(),
"[json.exception.type_error.302] type must be object, "
"but is boolean", json::type_error&);
"but is boolean",
json::type_error&);
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",
json::type_error&);
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",
json::type_error&);
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)")
{
const json::object_t o_reference = {{"object", json::object()},
{"array", {1, 2, 3, 4}},
{"number", 42},
{"boolean", false},
{"null", nullptr},
{"string", "Hello world"}
};
{"array", {1, 2, 3, 4}},
{"number", 42},
{"boolean", false},
{"null", nullptr},
{"string", "Hello world"}};
json j(o_reference);
SECTION("json::object_t")
@@ -156,12 +161,11 @@ TEST_CASE("value conversion")
SECTION("get an object (implicit)")
{
const json::object_t o_reference = {{"object", json::object()},
{"array", {1, 2, 3, 4}},
{"number", 42},
{"boolean", false},
{"null", nullptr},
{"string", "Hello world"}
};
{"array", {1, 2, 3, 4}},
{"number", 42},
{"boolean", false},
{"null", nullptr},
{"string", "Hello world"}};
json j(o_reference);
SECTION("json::object_t")
@@ -198,8 +202,7 @@ TEST_CASE("value conversion")
SECTION("get an array (explicit)")
{
const json::array_t a_reference{json(1), json(1u), json(2.2),
json(false), json("string"), json()};
const json::array_t a_reference{json(1), json(1u), json(2.2), json(false), json("string"), json()};
json j(a_reference);
SECTION("json::array_t")
@@ -221,7 +224,8 @@ TEST_CASE("value conversion")
CHECK_THROWS_WITH_AS(
json(json::value_t::null).get<std::forward_list<json>>(),
"[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&);
}
SECTION("std::vector<json>")
@@ -231,7 +235,8 @@ TEST_CASE("value conversion")
CHECK_THROWS_WITH_AS(
json(json::value_t::null).get<std::vector<json>>(),
"[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&);
#if !defined(JSON_NOEXCEPTION)
SECTION("reserve is called on containers that supports it")
@@ -246,8 +251,8 @@ TEST_CASE("value conversion")
SECTION("built-in arrays")
{
const char str[] = "a string"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const int nbs[] = {0, 1, 2}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const char str[] = "a string"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const int nbs[] = {0, 1, 2}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const json j2 = nbs;
const json j3 = str;
@@ -268,35 +273,42 @@ TEST_CASE("value conversion")
{
CHECK_THROWS_WITH_AS(
json(json::value_t::object).get<std::vector<int>>(),
"[json.exception.type_error.302] type must be array, but is object", json::type_error&);
"[json.exception.type_error.302] type must be array, but is object",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::null).get<json::array_t>(),
"[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(json::value_t::object).get<json::array_t>(),
"[json.exception.type_error.302] type must be array, but is object", json::type_error&);
"[json.exception.type_error.302] type must be array, but is object",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::string).get<json::array_t>(),
"[json.exception.type_error.302] type must be array, but is string", json::type_error&);
"[json.exception.type_error.302] type must be array, but is string",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::boolean).get<json::array_t>(),
"[json.exception.type_error.302] type must be array, but is boolean", json::type_error&);
"[json.exception.type_error.302] type must be array, but is boolean",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::number_integer).get<json::array_t>(),
"[json.exception.type_error.302] type must be array, but is number", json::type_error&);
"[json.exception.type_error.302] type must be array, but is number",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::number_unsigned).get<json::array_t>(),
"[json.exception.type_error.302] type must be array, but is number", json::type_error&);
"[json.exception.type_error.302] type must be array, but is number",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::number_float).get<json::array_t>(),
"[json.exception.type_error.302] type must be array, but is number", json::type_error&);
"[json.exception.type_error.302] type must be array, but is number",
json::type_error&);
}
}
SECTION("get an array (explicit, get_to)")
{
const json::array_t a_reference{json(1), json(1u), json(2.2),
json(false), json("string"), json()};
const json::array_t a_reference{json(1), json(1u), json(2.2), json(false), json("string"), json()};
json j(a_reference);
SECTION("json::array_t")
@@ -336,8 +348,8 @@ TEST_CASE("value conversion")
SECTION("built-in arrays")
{
const int nbs[] = {0, 1, 2}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
int nbs2[] = {0, 0, 0}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const int nbs[] = {0, 1, 2}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
int nbs2[] = {0, 0, 0}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const json j2 = nbs;
j2.get_to(nbs2);
@@ -355,8 +367,7 @@ TEST_CASE("value conversion")
#if JSON_USE_IMPLICIT_CONVERSIONS
SECTION("get an array (implicit)")
{
const json::array_t a_reference{json(1), json(1u), json(2.2),
json(false), json("string"), json()};
const json::array_t a_reference{json(1), json(1u), json(2.2), json(false), json("string"), json()};
json j(a_reference);
SECTION("json::array_t")
@@ -419,44 +430,58 @@ TEST_CASE("value conversion")
{
CHECK_THROWS_WITH_AS(
json(json::value_t::null).get<json::string_t>(),
"[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<json::string_t>(),
"[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<json::string_t>(),
"[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<json::string_t>(),
"[json.exception.type_error.302] type must be string, "
"but is boolean", json::type_error&);
"but is boolean",
json::type_error&);
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",
json::type_error&);
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",
json::type_error&);
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)
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>(),
"[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>(),
"[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>(),
"[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>(),
"[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>(),
"[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>(),
"[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>(),
"[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
}
@@ -499,19 +524,26 @@ TEST_CASE("value conversion")
CHECK(n2 == n);
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>(),
"[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>(),
"[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>(),
"[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>(),
"[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>(),
"[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>(),
"[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
@@ -526,13 +558,13 @@ TEST_CASE("value conversion")
CHECK(json(s) == j);
}
#if defined(JSON_HAS_CPP_17)
#if defined(JSON_HAS_CPP_17)
SECTION("std::string_view")
{
std::string_view const s = j.get<std::string_view>();
CHECK(json(s) == j);
}
#endif
#endif
SECTION("std::string")
{
@@ -572,28 +604,35 @@ TEST_CASE("value conversion")
CHECK_THROWS_WITH_AS(
json(json::value_t::null).get<json::boolean_t>(),
"[json.exception.type_error.302] type must be boolean, but is null", json::type_error&);
"[json.exception.type_error.302] type must be boolean, but is null",
json::type_error&);
CHECK_THROWS_WITH_AS(json(json::value_t::object).get<json::boolean_t>(),
"[json.exception.type_error.302] type must be boolean, "
"but is object", json::type_error&);
"but is object",
json::type_error&);
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>(),
"[json.exception.type_error.302] type must be boolean, "
"but is string", json::type_error&);
"but is string",
json::type_error&);
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 "
"number", json::type_error&);
"number",
json::type_error&);
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 "
"number", json::type_error&);
"number",
json::type_error&);
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 "
"number", json::type_error&);
"number",
json::type_error&);
}
}
@@ -832,20 +871,25 @@ TEST_CASE("value conversion")
{
CHECK_THROWS_WITH_AS(
json(json::value_t::null).get<json::number_integer_t>(),
"[json.exception.type_error.302] type must be number, but is null", json::type_error&);
"[json.exception.type_error.302] type must be number, but is null",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::object).get<json::number_integer_t>(),
"[json.exception.type_error.302] type must be number, but is object", json::type_error&);
"[json.exception.type_error.302] type must be number, but is object",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::array).get<json::number_integer_t>(),
"[json.exception.type_error.302] type must be number, but is array", json::type_error&);
"[json.exception.type_error.302] type must be number, but is array",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::string).get<json::number_integer_t>(),
"[json.exception.type_error.302] type must be number, but is string", json::type_error&);
"[json.exception.type_error.302] type must be number, but is string",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::boolean).get<json::number_integer_t>(),
"[json.exception.type_error.302] type must be number, but is "
"boolean", json::type_error&);
"boolean",
json::type_error&);
CHECK_NOTHROW(
json(json::value_t::number_float).get<json::number_integer_t>());
@@ -1095,20 +1139,25 @@ TEST_CASE("value conversion")
{
CHECK_THROWS_WITH_AS(
json(json::value_t::null).get<json::number_float_t>(),
"[json.exception.type_error.302] type must be number, but is null", json::type_error&);
"[json.exception.type_error.302] type must be number, but is null",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::object).get<json::number_float_t>(),
"[json.exception.type_error.302] type must be number, but is object", json::type_error&);
"[json.exception.type_error.302] type must be number, but is object",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::array).get<json::number_float_t>(),
"[json.exception.type_error.302] type must be number, but is array", json::type_error&);
"[json.exception.type_error.302] type must be number, but is array",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::string).get<json::number_float_t>(),
"[json.exception.type_error.302] type must be number, but is string", json::type_error&);
"[json.exception.type_error.302] type must be number, but is string",
json::type_error&);
CHECK_THROWS_WITH_AS(
json(json::value_t::boolean).get<json::number_float_t>(),
"[json.exception.type_error.302] type must be number, but is "
"boolean", json::type_error&);
"boolean",
json::type_error&);
CHECK_NOTHROW(
json(json::value_t::number_integer).get<json::number_float_t>());
@@ -1265,8 +1314,16 @@ TEST_CASE("value conversion")
SECTION("get an enum")
{
enum c_enum { value_1, value_2 };
enum class cpp_enum { value_1, value_2 };
enum c_enum
{
value_1,
value_2
};
enum class cpp_enum
{
value_1,
value_2
};
CHECK(json(value_1).get<c_enum>() == value_1);
CHECK(json(cpp_enum::value_1).get<cpp_enum>() == cpp_enum::value_1);
@@ -1325,7 +1382,8 @@ TEST_CASE("value conversion")
{
CHECK_THROWS_WITH_AS(
(json().get<std::map<std::string, int>>()),
"[json.exception.type_error.302] type must be object, but is null", json::type_error&);
"[json.exception.type_error.302] type must be object, but is null",
json::type_error&);
}
}
@@ -1367,7 +1425,8 @@ TEST_CASE("value conversion")
{
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] "
"array index 4 is out of range", json::out_of_range&);
"array index 4 is out of range",
json::out_of_range&);
}
SECTION("std::array is smaller than JSON")
@@ -1436,10 +1495,12 @@ TEST_CASE("value conversion")
json const j8 = 2;
CHECK_THROWS_WITH_AS((j7.get<std::map<int, int>>()),
"[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>>()),
"[json.exception.type_error.302] type must be array, "
"but is number", json::type_error&);
"but is number",
json::type_error&);
SECTION("superfluous entries")
{
@@ -1461,10 +1522,12 @@ TEST_CASE("value conversion")
json const j8 = 2;
CHECK_THROWS_WITH_AS((j7.get<std::unordered_map<int, int>>()),
"[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>>()),
"[json.exception.type_error.302] type must be array, "
"but is number", json::type_error&);
"but is number",
json::type_error&);
SECTION("superfluous entries")
{
@@ -1480,38 +1543,48 @@ TEST_CASE("value conversion")
// that's what I thought when other test like this one broke
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.exception.type_error.302] type must be array, but is null",
json::type_error&);
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&);
"[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&);
"[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&);
"[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&);
"[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
NLOHMANN_JSON_SERIALIZE_ENUM(cards,
{
{cards::kreuz, "kreuz"},
{cards::pik, "pik"},
{cards::pik, "puk"}, // second entry for cards::puk; will not be used
{cards::herz, "herz"},
{cards::karo, "karo"}
})
{{cards::kreuz, "kreuz"},
{cards::pik, "pik"},
{cards::pik, "puk"}, // second entry for cards::puk; will not be used
{cards::herz, "herz"},
{cards::karo, "karo"}})
enum TaskState
{
@@ -1523,12 +1596,12 @@ enum TaskState
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
NLOHMANN_JSON_SERIALIZE_ENUM(TaskState,
{
{TS_INVALID, nullptr},
{TS_STOPPED, "stopped"},
{TS_RUNNING, "running"},
{TS_COMPLETED, "completed"},
})
{
{TS_INVALID, nullptr},
{TS_STOPPED, "stopped"},
{TS_RUNNING, "running"},
{TS_COMPLETED, "completed"},
})
TEST_CASE("JSON to enum mapping")
{
+114 -118
View File
@@ -30,25 +30,25 @@ class json_metadata
{
return m_metadata;
}
private:
metadata_t m_metadata = {};
};
template<class T>
using json_with_metadata =
nlohmann::basic_json <
std::map,
std::vector,
std::string,
bool,
std::int64_t,
std::uint64_t,
double,
std::allocator,
nlohmann::adl_serializer,
std::vector<std::uint8_t>,
json_metadata<T>
>;
nlohmann::basic_json<
std::map,
std::vector,
std::string,
bool,
std::int64_t,
std::uint64_t,
double,
std::allocator,
nlohmann::adl_serializer,
std::vector<std::uint8_t>,
json_metadata<T>>;
TEST_CASE("JSON Node Metadata")
{
@@ -56,18 +56,18 @@ TEST_CASE("JSON Node Metadata")
{
using json = json_with_metadata<int>;
json null;
auto obj = json::object();
auto obj = json::object();
auto array = json::array();
null.metadata() = 1;
obj.metadata() = 2;
null.metadata() = 1;
obj.metadata() = 2;
array.metadata() = 3;
auto copy = array;
CHECK(null.metadata() == 1);
CHECK(obj.metadata() == 2);
CHECK(null.metadata() == 1);
CHECK(obj.metadata() == 2);
CHECK(array.metadata() == 3);
CHECK(copy.metadata() == 3);
CHECK(copy.metadata() == 3);
}
SECTION("type vector<int>")
{
@@ -77,11 +77,11 @@ TEST_CASE("JSON Node Metadata")
auto copy = value;
value.metadata().emplace_back(2);
CHECK(copy.metadata().size() == 1);
CHECK(copy.metadata().at(0) == 1);
CHECK(copy.metadata().size() == 1);
CHECK(copy.metadata().at(0) == 1);
CHECK(value.metadata().size() == 2);
CHECK(value.metadata().at(0) == 1);
CHECK(value.metadata().at(1) == 2);
CHECK(value.metadata().at(0) == 1);
CHECK(value.metadata().at(1) == 2);
}
SECTION("copy ctor")
{
@@ -92,15 +92,15 @@ TEST_CASE("JSON Node Metadata")
json copy = value;
CHECK(copy.metadata().size() == 2);
CHECK(copy.metadata().at(0) == 1);
CHECK(copy.metadata().at(1) == 2);
CHECK(copy.metadata().size() == 2);
CHECK(copy.metadata().at(0) == 1);
CHECK(copy.metadata().at(1) == 2);
CHECK(value.metadata().size() == 2);
CHECK(value.metadata().at(0) == 1);
CHECK(value.metadata().at(1) == 2);
CHECK(value.metadata().at(0) == 1);
CHECK(value.metadata().at(1) == 2);
value.metadata().clear();
CHECK(copy.metadata().size() == 2);
CHECK(copy.metadata().size() == 2);
CHECK(value.metadata().size() == 0);
}
SECTION("move ctor")
@@ -112,9 +112,9 @@ TEST_CASE("JSON Node Metadata")
const json moved = std::move(value);
CHECK(moved.metadata().size() == 2);
CHECK(moved.metadata().at(0) == 1);
CHECK(moved.metadata().at(1) == 2);
CHECK(moved.metadata().size() == 2);
CHECK(moved.metadata().at(0) == 1);
CHECK(moved.metadata().at(1) == 2);
}
SECTION("move assign")
{
@@ -126,9 +126,9 @@ TEST_CASE("JSON Node Metadata")
json moved;
moved = std::move(value);
CHECK(moved.metadata().size() == 2);
CHECK(moved.metadata().at(0) == 1);
CHECK(moved.metadata().at(1) == 2);
CHECK(moved.metadata().size() == 2);
CHECK(moved.metadata().at(0) == 1);
CHECK(moved.metadata().at(1) == 2);
}
SECTION("copy assign")
{
@@ -140,22 +140,22 @@ TEST_CASE("JSON Node Metadata")
json copy;
copy = value;
CHECK(copy.metadata().size() == 2);
CHECK(copy.metadata().at(0) == 1);
CHECK(copy.metadata().at(1) == 2);
CHECK(copy.metadata().size() == 2);
CHECK(copy.metadata().at(0) == 1);
CHECK(copy.metadata().at(1) == 2);
CHECK(value.metadata().size() == 2);
CHECK(value.metadata().at(0) == 1);
CHECK(value.metadata().at(1) == 2);
CHECK(value.metadata().at(0) == 1);
CHECK(value.metadata().at(1) == 2);
value.metadata().clear();
CHECK(copy.metadata().size() == 2);
CHECK(copy.metadata().size() == 2);
CHECK(value.metadata().size() == 0);
}
SECTION("type unique_ptr<int>")
{
using json = json_with_metadata<std::unique_ptr<int>>;
json value;
value.metadata().reset(new int(42)); // NOLINT(cppcoreguidelines-owning-memory)
value.metadata().reset(new int(42)); // NOLINT(cppcoreguidelines-owning-memory)
auto moved = std::move(value);
CHECK(moved.metadata() != nullptr);
@@ -171,14 +171,14 @@ TEST_CASE("JSON Node Metadata")
json const array(10, value);
CHECK(value.metadata().size() == 2);
CHECK(value.metadata().at(0) == 1);
CHECK(value.metadata().at(1) == 2);
CHECK(value.metadata().at(0) == 1);
CHECK(value.metadata().at(1) == 2);
for (const auto& val : array)
{
CHECK(val.metadata().size() == 2);
CHECK(val.metadata().at(0) == 1);
CHECK(val.metadata().at(1) == 2);
CHECK(val.metadata().at(0) == 1);
CHECK(val.metadata().at(1) == 2);
}
}
}
@@ -188,38 +188,38 @@ TEST_CASE("JSON Node Metadata")
class visitor_adaptor
{
public:
template <class Fnc>
template<class Fnc>
void visit(const Fnc& fnc) const;
private:
template <class Ptr, class Fnc>
template<class Ptr, class Fnc>
void do_visit(const Ptr& ptr, const Fnc& fnc) const;
};
using json_with_visitor_t = nlohmann::basic_json <
std::map,
std::vector,
std::string,
bool,
std::int64_t,
std::uint64_t,
double,
std::allocator,
nlohmann::adl_serializer,
std::vector<std::uint8_t>,
visitor_adaptor
>;
using json_with_visitor_t = nlohmann::basic_json<
std::map,
std::vector,
std::string,
bool,
std::int64_t,
std::uint64_t,
double,
std::allocator,
nlohmann::adl_serializer,
std::vector<std::uint8_t>,
visitor_adaptor>;
template <class Fnc>
template<class Fnc>
void visitor_adaptor::visit(const Fnc& fnc) const
{
do_visit(json_with_visitor_t::json_pointer{}, fnc);
}
template <class Ptr, class Fnc>
template<class Ptr, class Fnc>
void visitor_adaptor::do_visit(const Ptr& ptr, const Fnc& fnc) const
{
using value_t = nlohmann::detail::value_t;
const json_with_visitor_t& json = *static_cast<const json_with_visitor_t*>(this); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
const json_with_visitor_t& json = *static_cast<const json_with_visitor_t*>(this); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
switch (json.type())
{
case value_t::object:
@@ -252,7 +252,7 @@ TEST_CASE("JSON Visit Node")
{
json_with_visitor_t json;
json["null"];
json["int"] = -1;
json["int"] = -1;
json["uint"] = 1U;
json["float"] = 1.0;
json["boolean"] = true;
@@ -261,8 +261,7 @@ TEST_CASE("JSON Visit Node")
json["array"].push_back(1);
json["array"].push_back(json);
std::set<std::string> expected
{
std::set<std::string> expected{
"/null - null - null",
"/int - number_integer - -1",
"/uint - number_unsigned - 1",
@@ -279,58 +278,55 @@ TEST_CASE("JSON Visit Node")
"/array/2/boolean - boolean - true",
"/array/2/string - string - \"string\"",
"/array/2/array/0 - number_integer - 0",
"/array/2/array/1 - number_integer - 1"
};
"/array/2/array/1 - number_integer - 1"};
json.visit(
[&](const json_with_visitor_t::json_pointer & p,
const json_with_visitor_t& j)
{
std::stringstream str;
str << p.to_string() << " - " ;
using value_t = nlohmann::detail::value_t;
switch (j.type())
{
case value_t::object:
str << "object";
break;
case value_t::array:
str << "array";
break;
case value_t::discarded:
str << "discarded";
break;
case value_t::null:
str << "null";
break;
case value_t::string:
str << "string";
break;
case value_t::boolean:
str << "boolean";
break;
case value_t::number_integer:
str << "number_integer";
break;
case value_t::number_unsigned:
str << "number_unsigned";
break;
case value_t::number_float:
str << "number_float";
break;
case value_t::binary:
str << "binary";
break;
default:
str << "error";
break;
}
str << " - " << j.dump();
CHECK(json.at(p) == j);
INFO(str.str());
CHECK(expected.count(str.str()) == 1);
expected.erase(str.str());
}
);
[&](const json_with_visitor_t::json_pointer& p,
const json_with_visitor_t& j) {
std::stringstream str;
str << p.to_string() << " - ";
using value_t = nlohmann::detail::value_t;
switch (j.type())
{
case value_t::object:
str << "object";
break;
case value_t::array:
str << "array";
break;
case value_t::discarded:
str << "discarded";
break;
case value_t::null:
str << "null";
break;
case value_t::string:
str << "string";
break;
case value_t::boolean:
str << "boolean";
break;
case value_t::number_integer:
str << "number_integer";
break;
case value_t::number_unsigned:
str << "number_unsigned";
break;
case value_t::number_float:
str << "number_float";
break;
case value_t::binary:
str << "binary";
break;
default:
str << "error";
break;
}
str << " - " << j.dump();
CHECK(json.at(p) == j);
INFO(str.str());
CHECK(expected.count(str.str()) == 1);
expected.erase(str.str());
});
CHECK(expected.empty());
}
+40 -115
View File
@@ -12,7 +12,7 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#ifdef JSON_TEST_NO_GLOBAL_UDLS
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
#endif
#include <iostream>
@@ -20,8 +20,7 @@ using nlohmann::json;
#include <sstream>
#include <valarray>
namespace
{
namespace {
struct SaxEventLogger : public nlohmann::json_sax<json>
{
bool null() override
@@ -125,7 +124,7 @@ struct SaxEventLogger : public nlohmann::json_sax<json>
return false;
}
std::vector<std::string> events {};
std::vector<std::string> events{};
};
struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger
@@ -169,7 +168,7 @@ struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
}
};
template <typename T>
template<typename T>
class proxy_iterator
{
public:
@@ -182,7 +181,9 @@ class proxy_iterator
using iterator_category = std::input_iterator_tag;
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++()
{
@@ -214,7 +215,7 @@ class proxy_iterator
private:
iterator* m_it = nullptr;
};
} // namespace
} // namespace
TEST_CASE("deserialization")
{
@@ -236,12 +237,7 @@ TEST_CASE("deserialization")
CHECK(json::sax_parse(ss3, &l));
CHECK(l.events.size() == 11);
CHECK(l.events == std::vector<std::string>(
{
"start_array()", "string(foo)", "number_unsigned(1)",
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
"start_object()", "key(one)", "number_unsigned(1)",
"end_object()", "end_array()"
}));
{"start_array()", "string(foo)", "number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", "start_object()", "key(one)", "number_unsigned(1)", "end_object()", "end_array()"}));
}
SECTION("string literal")
@@ -255,12 +251,7 @@ TEST_CASE("deserialization")
CHECK(json::sax_parse(s, &l));
CHECK(l.events.size() == 11);
CHECK(l.events == std::vector<std::string>(
{
"start_array()", "string(foo)", "number_unsigned(1)",
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
"start_object()", "key(one)", "number_unsigned(1)",
"end_object()", "end_array()"
}));
{"start_array()", "string(foo)", "number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", "start_object()", "key(one)", "number_unsigned(1)", "end_object()", "end_array()"}));
}
SECTION("string_t")
@@ -274,12 +265,7 @@ TEST_CASE("deserialization")
CHECK(json::sax_parse(s, &l));
CHECK(l.events.size() == 11);
CHECK(l.events == std::vector<std::string>(
{
"start_array()", "string(foo)", "number_unsigned(1)",
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
"start_object()", "key(one)", "number_unsigned(1)",
"end_object()", "end_array()"
}));
{"start_array()", "string(foo)", "number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", "start_object()", "key(one)", "number_unsigned(1)", "end_object()", "end_array()"}));
}
SECTION("operator<<")
@@ -331,12 +317,7 @@ TEST_CASE("deserialization")
CHECK(!json::sax_parse(ss5, &l));
CHECK(l.events.size() == 11);
CHECK(l.events == std::vector<std::string>(
{
"start_array()", "string(foo)", "number_unsigned(1)",
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
"start_object()", "key(one)", "number_unsigned(1)",
"end_object()", "parse_error(29)"
}));
{"start_array()", "string(foo)", "number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", "start_object()", "key(one)", "number_unsigned(1)", "end_object()", "parse_error(29)"}));
}
SECTION("string")
@@ -354,12 +335,7 @@ TEST_CASE("deserialization")
CHECK(!json::sax_parse(s, &l));
CHECK(l.events.size() == 11);
CHECK(l.events == std::vector<std::string>(
{
"start_array()", "string(foo)", "number_unsigned(1)",
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
"start_object()", "key(one)", "number_unsigned(1)",
"end_object()", "parse_error(29)"
}));
{"start_array()", "string(foo)", "number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", "start_object()", "key(one)", "number_unsigned(1)", "end_object()", "parse_error(29)"}));
}
SECTION("operator<<")
@@ -402,7 +378,7 @@ TEST_CASE("deserialization")
SECTION("from std::array")
{
std::array<uint8_t, 5> const v { {'t', 'r', 'u', 'e'} };
std::array<uint8_t, 5> const v{{'t', 'r', 'u', 'e'}};
CHECK(json::parse(v) == json(true));
CHECK(json::accept(v));
@@ -414,7 +390,7 @@ TEST_CASE("deserialization")
SECTION("from array")
{
uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
CHECK(json::parse(v) == json(true));
CHECK(json::accept(v));
@@ -426,7 +402,7 @@ TEST_CASE("deserialization")
SECTION("from chars")
{
auto* v = new uint8_t[5]; // NOLINT(cppcoreguidelines-owning-memory)
auto* v = new uint8_t[5]; // NOLINT(cppcoreguidelines-owning-memory)
v[0] = 't';
v[1] = 'r';
v[2] = 'u';
@@ -440,7 +416,7 @@ TEST_CASE("deserialization")
CHECK(l.events.size() == 1);
CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
delete[] v; // NOLINT(cppcoreguidelines-owning-memory)
delete[] v; // NOLINT(cppcoreguidelines-owning-memory)
}
SECTION("from std::string")
@@ -493,12 +469,11 @@ TEST_CASE("deserialization")
CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
CHECK(l.events.size() == 1);
CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
}
SECTION("from std::array")
{
std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };
std::array<uint8_t, 5> v{{'t', 'r', 'u', 'e'}};
CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
CHECK(json::accept(std::begin(v), std::end(v)));
@@ -510,7 +485,7 @@ TEST_CASE("deserialization")
SECTION("from array")
{
uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
CHECK(json::accept(std::begin(v), std::end(v)));
@@ -585,8 +560,7 @@ TEST_CASE("deserialization")
json j;
json_sax_dom_parser<json> sax(j, true);
CHECK(json::sax_parse(proxy(first), proxy(last), &sax,
input_format_t::json, false));
CHECK(json::sax_parse(proxy(first), proxy(last), &sax, input_format_t::json, false));
CHECK(j.dump() == str1);
CHECK(std::string(first, last) == str2);
}
@@ -865,10 +839,7 @@ TEST_CASE("deserialization")
CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
CHECK(l.events.size() == 4);
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)"}));
}
}
}
@@ -888,9 +859,7 @@ TEST_CASE("deserialization")
CHECK(!json::sax_parse(bom, &l));
CHECK(l.events.size() == 1);
CHECK(l.events == std::vector<std::string>(
{
"parse_error(4)"
}));
{"parse_error(4)"}));
}
SECTION("BOM and content")
@@ -904,14 +873,10 @@ TEST_CASE("deserialization")
CHECK(json::sax_parse(bom + "1", &l2));
CHECK(l1.events.size() == 1);
CHECK(l1.events == std::vector<std::string>(
{
"number_unsigned(1)"
}));
{"number_unsigned(1)"}));
CHECK(l2.events.size() == 1);
CHECK(l2.events == std::vector<std::string>(
{
"number_unsigned(1)"
}));
{"number_unsigned(1)"}));
}
SECTION("2 byte of BOM")
@@ -927,14 +892,10 @@ TEST_CASE("deserialization")
CHECK(!json::sax_parse(bom.substr(0, 2), &l2));
CHECK(l1.events.size() == 1);
CHECK(l1.events == std::vector<std::string>(
{
"parse_error(3)"
}));
{"parse_error(3)"}));
CHECK(l2.events.size() == 1);
CHECK(l2.events == std::vector<std::string>(
{
"parse_error(3)"
}));
{"parse_error(3)"}));
}
SECTION("1 byte of BOM")
@@ -950,14 +911,10 @@ TEST_CASE("deserialization")
CHECK(!json::sax_parse(bom.substr(0, 1), &l2));
CHECK(l1.events.size() == 1);
CHECK(l1.events == std::vector<std::string>(
{
"parse_error(2)"
}));
{"parse_error(2)"}));
CHECK(l2.events.size() == 1);
CHECK(l2.events == std::vector<std::string>(
{
"parse_error(2)"
}));
{"parse_error(2)"}));
}
SECTION("variations")
@@ -990,9 +947,7 @@ TEST_CASE("deserialization")
CHECK(json::sax_parse(s + "null", &l));
CHECK(l.events.size() == 1);
CHECK(l.events == std::vector<std::string>(
{
"null()"
}));
{"null()"}));
}
else
{
@@ -1008,23 +963,17 @@ TEST_CASE("deserialization")
if (i0 != 0)
{
CHECK(l.events == std::vector<std::string>(
{
"parse_error(1)"
}));
{"parse_error(1)"}));
}
else if (i1 != 0)
{
CHECK(l.events == std::vector<std::string>(
{
"parse_error(2)"
}));
{"parse_error(2)"}));
}
else
{
CHECK(l.events == std::vector<std::string>(
{
"parse_error(3)"
}));
{"parse_error(3)"}));
}
}
}
@@ -1055,37 +1004,22 @@ TEST_CASE("deserialization")
json::sax_parse(s, &default_logger);
CHECK(default_logger.events.size() == 14);
CHECK(default_logger.events == std::vector<std::string>(
{
"start_array()", "number_unsigned(1)", "start_array()",
"string(string)", "number_float(43.12)", "end_array()", "null()",
"start_object()", "key(key1)", "boolean(true)", "key(key2)",
"boolean(false)", "end_object()", "end_array()"
}));
{"start_array()", "number_unsigned(1)", "start_array()", "string(string)", "number_float(43.12)", "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);
CHECK(exit_after_start_object.events.size() == 8);
CHECK(exit_after_start_object.events == std::vector<std::string>(
{
"start_array()", "number_unsigned(1)", "start_array()",
"string(string)", "number_float(43.12)", "end_array()", "null()",
"start_object()"
}));
{"start_array()", "number_unsigned(1)", "start_array()", "string(string)", "number_float(43.12)", "end_array()", "null()", "start_object()"}));
json::sax_parse(s, &exit_after_key);
CHECK(exit_after_key.events.size() == 9);
CHECK(exit_after_key.events == std::vector<std::string>(
{
"start_array()", "number_unsigned(1)", "start_array()",
"string(string)", "number_float(43.12)", "end_array()", "null()",
"start_object()", "key(key1)"
}));
{"start_array()", "number_unsigned(1)", "start_array()", "string(string)", "number_float(43.12)", "end_array()", "null()", "start_object()", "key(key1)"}));
json::sax_parse(s, &exit_after_start_array);
CHECK(exit_after_start_array.events.size() == 1);
CHECK(exit_after_start_array.events == std::vector<std::string>(
{
"start_array()"
}));
{"start_array()"}));
}
SECTION("JSON Lines")
@@ -1131,13 +1065,7 @@ TEST_CASE("deserialization")
}
}
TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)", T,
char, unsigned char, signed char,
wchar_t,
char16_t, char32_t,
std::uint8_t, std::int8_t,
std::int16_t, std::uint16_t,
std::int32_t, std::uint32_t)
TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)", T, char, unsigned char, signed char, wchar_t, char16_t, char32_t, std::uint8_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'};
CHECK(json::parse(v) == json(true));
@@ -1149,8 +1077,7 @@ TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)", T,
CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
}
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-8)", T,
char, unsigned char, std::uint8_t)
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-8)", T, char, unsigned char, std::uint8_t)
{
// 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), '"'};
@@ -1162,8 +1089,7 @@ TEST_CASE_TEMPLATE("deserialization of different character types (UTF-8)", T,
CHECK(l.events.size() == 1);
}
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-16)", T,
char16_t, std::uint16_t)
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-16)", T, char16_t, std::uint16_t)
{
// a star emoji
std::vector<T> const v = {static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"')};
@@ -1175,8 +1101,7 @@ TEST_CASE_TEMPLATE("deserialization of different character types (UTF-16)", T,
CHECK(l.events.size() == 1);
}
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-32)", T,
char32_t, std::uint32_t)
TEST_CASE_TEMPLATE("deserialization of different character types (UTF-32)", T, char32_t, std::uint32_t)
{
// a star emoji
std::vector<T> const v = {static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"')};
+6 -4
View File
@@ -23,11 +23,13 @@ using json = nlohmann::json;
class sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>
{
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)
{
error_string = new std::string(ex.what()); // NOLINT(cppcoreguidelines-owning-memory)
error_string = new std::string(ex.what()); // NOLINT(cppcoreguidelines-owning-memory)
return false;
}
@@ -43,9 +45,9 @@ TEST_CASE("Tests with disabled exceptions")
json 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'");
delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)
delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)
}
}
+22 -11
View File
@@ -45,9 +45,11 @@ TEST_CASE("element access 1")
SECTION("access outside bounds")
{
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&);
"[json.exception.out_of_range.401] array index 8 is out of range",
json::out_of_range&);
}
SECTION("access on non-array type")
@@ -359,26 +361,34 @@ TEST_CASE("element access 1")
json jarray2 = {"foo", "bar"};
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()),
"[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()),
"[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()),
"[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 const jarray2 = {"foo", "bar"};
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()),
"[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()),
"[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()),
"[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&);
}
}
}
@@ -530,7 +540,8 @@ TEST_CASE("element access 1")
{
json j;
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&);
}
}
File diff suppressed because it is too large Load Diff
+42 -42
View File
@@ -23,42 +23,42 @@ TEST_CASE("hash<nlohmann::json>")
std::set<std::size_t> hashes;
// null
hashes.insert(std::hash<json> {}(json(nullptr)));
hashes.insert(std::hash<json>{}(json(nullptr)));
// boolean
hashes.insert(std::hash<json> {}(json(true)));
hashes.insert(std::hash<json> {}(json(false)));
hashes.insert(std::hash<json>{}(json(true)));
hashes.insert(std::hash<json>{}(json(false)));
// string
hashes.insert(std::hash<json> {}(json("")));
hashes.insert(std::hash<json> {}(json("foo")));
hashes.insert(std::hash<json>{}(json("")));
hashes.insert(std::hash<json>{}(json("foo")));
// number
hashes.insert(std::hash<json> {}(json(0)));
hashes.insert(std::hash<json> {}(json(static_cast<unsigned>(0))));
hashes.insert(std::hash<json>{}(json(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)));
hashes.insert(std::hash<json> {}(json(42.23)));
hashes.insert(std::hash<json>{}(json(-1)));
hashes.insert(std::hash<json>{}(json(0.0)));
hashes.insert(std::hash<json>{}(json(42.23)));
// array
hashes.insert(std::hash<json> {}(json::array()));
hashes.insert(std::hash<json> {}(json::array({1, 2, 3})));
hashes.insert(std::hash<json>{}(json::array()));
hashes.insert(std::hash<json>{}(json::array({1, 2, 3})));
// object
hashes.insert(std::hash<json> {}(json::object()));
hashes.insert(std::hash<json> {}(json::object({{"foo", "bar"}})));
hashes.insert(std::hash<json>{}(json::object()));
hashes.insert(std::hash<json>{}(json::object({{"foo", "bar"}})));
// binary
hashes.insert(std::hash<json> {}(json::binary({})));
hashes.insert(std::hash<json> {}(json::binary({}, 0)));
hashes.insert(std::hash<json> {}(json::binary({}, 42)));
hashes.insert(std::hash<json> {}(json::binary({1, 2, 3})));
hashes.insert(std::hash<json> {}(json::binary({1, 2, 3}, 0)));
hashes.insert(std::hash<json> {}(json::binary({1, 2, 3}, 42)));
hashes.insert(std::hash<json>{}(json::binary({})));
hashes.insert(std::hash<json>{}(json::binary({}, 0)));
hashes.insert(std::hash<json>{}(json::binary({}, 42)));
hashes.insert(std::hash<json>{}(json::binary({1, 2, 3})));
hashes.insert(std::hash<json>{}(json::binary({1, 2, 3}, 0)));
hashes.insert(std::hash<json>{}(json::binary({1, 2, 3}, 42)));
// discarded
hashes.insert(std::hash<json> {}(json(json::value_t::discarded)));
hashes.insert(std::hash<json>{}(json(json::value_t::discarded)));
CHECK(hashes.size() == 21);
}
@@ -72,42 +72,42 @@ TEST_CASE("hash<nlohmann::ordered_json>")
std::set<std::size_t> hashes;
// null
hashes.insert(std::hash<ordered_json> {}(ordered_json(nullptr)));
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)));
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")));
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(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)));
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})));
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"}})));
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)));
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)));
hashes.insert(std::hash<ordered_json>{}(ordered_json(ordered_json::value_t::discarded)));
CHECK(hashes.size() == 21);
}
+5 -6
View File
@@ -11,9 +11,9 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#include "make_test_data_available.hpp"
#include <fstream>
#include <sstream>
#include "make_test_data_available.hpp"
TEST_CASE("object inspection")
{
@@ -21,7 +21,7 @@ TEST_CASE("object inspection")
{
SECTION("object")
{
json const j {{"foo", 1}, {"bar", false}};
json const j{{"foo", 1}, {"bar", false}};
CHECK(!j.is_null());
CHECK(!j.is_boolean());
CHECK(!j.is_number());
@@ -39,7 +39,7 @@ TEST_CASE("object inspection")
SECTION("array")
{
json const j {"foo", 1, 1u, 42.23, false};
json const j{"foo", 1, 1u, 42.23, false};
CHECK(!j.is_null());
CHECK(!j.is_boolean());
CHECK(!j.is_number());
@@ -202,7 +202,7 @@ TEST_CASE("object inspection")
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")
{
@@ -329,8 +329,7 @@ TEST_CASE("object inspection")
SECTION("round trips")
{
for (const auto& s :
{"3.141592653589793", "1000000000000000010E5"
})
{"3.141592653589793", "1000000000000000010E5"})
{
json const j1 = json::parse(s);
std::string s1 = j1.dump();
+668 -670
View File
File diff suppressed because it is too large Load Diff
+80 -84
View File
@@ -59,14 +59,14 @@ TEST_CASE("iterators 2")
// comparison: not equal
{
// check definition
CHECK( (it1 != it1) == !(it1 == it1) );
CHECK( (it1 != it2) == !(it1 == it2) );
CHECK( (it1 != it3) == !(it1 == it3) );
CHECK( (it2 != it3) == !(it2 == it3) );
CHECK( (it1_c != it1_c) == !(it1_c == it1_c) );
CHECK( (it1_c != it2_c) == !(it1_c == it2_c) );
CHECK( (it1_c != it3_c) == !(it1_c == it3_c) );
CHECK( (it2_c != it3_c) == !(it2_c == it3_c) );
CHECK((it1 != it1) == !(it1 == it1));
CHECK((it1 != it2) == !(it1 == it2));
CHECK((it1 != it3) == !(it1 == it3));
CHECK((it2 != it3) == !(it2 == it3));
CHECK((it1_c != it1_c) == !(it1_c == it1_c));
CHECK((it1_c != it2_c) == !(it1_c == it2_c));
CHECK((it1_c != it3_c) == !(it1_c == it3_c));
CHECK((it2_c != it3_c) == !(it2_c == it3_c));
}
// comparison: smaller
@@ -133,14 +133,14 @@ TEST_CASE("iterators 2")
else
{
// check definition
CHECK( (it1 <= it1) == !(it1 < it1) );
CHECK( (it1 <= it2) == !(it2 < it1) );
CHECK( (it1 <= it3) == !(it3 < it1) );
CHECK( (it2 <= it3) == !(it3 < it2) );
CHECK( (it1_c <= it1_c) == !(it1_c < it1_c) );
CHECK( (it1_c <= it2_c) == !(it2_c < it1_c) );
CHECK( (it1_c <= it3_c) == !(it3_c < it1_c) );
CHECK( (it2_c <= it3_c) == !(it3_c < it2_c) );
CHECK((it1 <= it1) == !(it1 < it1));
CHECK((it1 <= it2) == !(it2 < it1));
CHECK((it1 <= it3) == !(it3 < it1));
CHECK((it2 <= it3) == !(it3 < it2));
CHECK((it1_c <= it1_c) == !(it1_c < it1_c));
CHECK((it1_c <= it2_c) == !(it2_c < it1_c));
CHECK((it1_c <= it3_c) == !(it3_c < it1_c));
CHECK((it2_c <= it3_c) == !(it3_c < it2_c));
}
}
@@ -171,14 +171,14 @@ TEST_CASE("iterators 2")
else
{
// check definition
CHECK( (it1 > it1) == (it1 < it1) );
CHECK( (it1 > it2) == (it2 < it1) );
CHECK( (it1 > it3) == (it3 < it1) );
CHECK( (it2 > it3) == (it3 < it2) );
CHECK( (it1_c > it1_c) == (it1_c < it1_c) );
CHECK( (it1_c > it2_c) == (it2_c < it1_c) );
CHECK( (it1_c > it3_c) == (it3_c < it1_c) );
CHECK( (it2_c > it3_c) == (it3_c < it2_c) );
CHECK((it1 > it1) == (it1 < it1));
CHECK((it1 > it2) == (it2 < it1));
CHECK((it1 > it3) == (it3 < it1));
CHECK((it2 > it3) == (it3 < it2));
CHECK((it1_c > it1_c) == (it1_c < it1_c));
CHECK((it1_c > it2_c) == (it2_c < it1_c));
CHECK((it1_c > it3_c) == (it3_c < it1_c));
CHECK((it2_c > it3_c) == (it3_c < it2_c));
}
}
@@ -209,14 +209,14 @@ TEST_CASE("iterators 2")
else
{
// check definition
CHECK( (it1 >= it1) == !(it1 < it1) );
CHECK( (it1 >= it2) == !(it1 < it2) );
CHECK( (it1 >= it3) == !(it1 < it3) );
CHECK( (it2 >= it3) == !(it2 < it3) );
CHECK( (it1_c >= it1_c) == !(it1_c < it1_c) );
CHECK( (it1_c >= it2_c) == !(it1_c < it2_c) );
CHECK( (it1_c >= it3_c) == !(it1_c < it3_c) );
CHECK( (it2_c >= it3_c) == !(it2_c < it3_c) );
CHECK((it1 >= it1) == !(it1 < it1));
CHECK((it1 >= it2) == !(it1 < it2));
CHECK((it1 >= it3) == !(it1 < it3));
CHECK((it2 >= it3) == !(it2 < it3));
CHECK((it1_c >= it1_c) == !(it1_c < it1_c));
CHECK((it1_c >= it2_c) == !(it1_c < it2_c));
CHECK((it1_c >= it3_c) == !(it1_c < it3_c));
CHECK((it2_c >= it3_c) == !(it2_c < it3_c));
}
}
}
@@ -483,14 +483,14 @@ TEST_CASE("iterators 2")
// comparison: not equal
{
// check definition
CHECK( (it1 != it1) == !(it1 == it1) );
CHECK( (it1 != it2) == !(it1 == it2) );
CHECK( (it1 != it3) == !(it1 == it3) );
CHECK( (it2 != it3) == !(it2 == it3) );
CHECK( (it1_c != it1_c) == !(it1_c == it1_c) );
CHECK( (it1_c != it2_c) == !(it1_c == it2_c) );
CHECK( (it1_c != it3_c) == !(it1_c == it3_c) );
CHECK( (it2_c != it3_c) == !(it2_c == it3_c) );
CHECK((it1 != it1) == !(it1 == it1));
CHECK((it1 != it2) == !(it1 == it2));
CHECK((it1 != it3) == !(it1 == it3));
CHECK((it2 != it3) == !(it2 == it3));
CHECK((it1_c != it1_c) == !(it1_c == it1_c));
CHECK((it1_c != it2_c) == !(it1_c == it2_c));
CHECK((it1_c != it3_c) == !(it1_c == it3_c));
CHECK((it2_c != it3_c) == !(it2_c == it3_c));
}
// comparison: smaller
@@ -557,14 +557,14 @@ TEST_CASE("iterators 2")
else
{
// check definition
CHECK( (it1 <= it1) == !(it1 < it1) );
CHECK( (it1 <= it2) == !(it2 < it1) );
CHECK( (it1 <= it3) == !(it3 < it1) );
CHECK( (it2 <= it3) == !(it3 < it2) );
CHECK( (it1_c <= it1_c) == !(it1_c < it1_c) );
CHECK( (it1_c <= it2_c) == !(it2_c < it1_c) );
CHECK( (it1_c <= it3_c) == !(it3_c < it1_c) );
CHECK( (it2_c <= it3_c) == !(it3_c < it2_c) );
CHECK((it1 <= it1) == !(it1 < it1));
CHECK((it1 <= it2) == !(it2 < it1));
CHECK((it1 <= it3) == !(it3 < it1));
CHECK((it2 <= it3) == !(it3 < it2));
CHECK((it1_c <= it1_c) == !(it1_c < it1_c));
CHECK((it1_c <= it2_c) == !(it2_c < it1_c));
CHECK((it1_c <= it3_c) == !(it3_c < it1_c));
CHECK((it2_c <= it3_c) == !(it3_c < it2_c));
}
}
@@ -595,14 +595,14 @@ TEST_CASE("iterators 2")
else
{
// check definition
CHECK( (it1 > it1) == (it1 < it1) );
CHECK( (it1 > it2) == (it2 < it1) );
CHECK( (it1 > it3) == (it3 < it1) );
CHECK( (it2 > it3) == (it3 < it2) );
CHECK( (it1_c > it1_c) == (it1_c < it1_c) );
CHECK( (it1_c > it2_c) == (it2_c < it1_c) );
CHECK( (it1_c > it3_c) == (it3_c < it1_c) );
CHECK( (it2_c > it3_c) == (it3_c < it2_c) );
CHECK((it1 > it1) == (it1 < it1));
CHECK((it1 > it2) == (it2 < it1));
CHECK((it1 > it3) == (it3 < it1));
CHECK((it2 > it3) == (it3 < it2));
CHECK((it1_c > it1_c) == (it1_c < it1_c));
CHECK((it1_c > it2_c) == (it2_c < it1_c));
CHECK((it1_c > it3_c) == (it3_c < it1_c));
CHECK((it2_c > it3_c) == (it3_c < it2_c));
}
}
@@ -633,14 +633,14 @@ TEST_CASE("iterators 2")
else
{
// check definition
CHECK( (it1 >= it1) == !(it1 < it1) );
CHECK( (it1 >= it2) == !(it1 < it2) );
CHECK( (it1 >= it3) == !(it1 < it3) );
CHECK( (it2 >= it3) == !(it2 < it3) );
CHECK( (it1_c >= it1_c) == !(it1_c < it1_c) );
CHECK( (it1_c >= it2_c) == !(it1_c < it2_c) );
CHECK( (it1_c >= it3_c) == !(it1_c < it3_c) );
CHECK( (it2_c >= it3_c) == !(it2_c < it3_c) );
CHECK((it1 >= it1) == !(it1 < it1));
CHECK((it1 >= it2) == !(it1 < it2));
CHECK((it1 >= it3) == !(it1 < it3));
CHECK((it2 >= it3) == !(it2 < it3));
CHECK((it1_c >= it1_c) == !(it1_c < it1_c));
CHECK((it1_c >= it2_c) == !(it1_c < it2_c));
CHECK((it1_c >= it3_c) == !(it1_c < it3_c));
CHECK((it2_c >= it3_c) == !(it2_c < it3_c));
}
}
}
@@ -894,7 +894,7 @@ TEST_CASE("iterators 2")
}
// libstdc++ algorithms don't work with Clang 15 (04/2022)
#if !DOCTEST_CLANG || (DOCTEST_CLANG && defined(__GLIBCXX__))
#if !DOCTEST_CLANG || (DOCTEST_CLANG && defined(__GLIBCXX__))
SECTION("algorithms")
{
SECTION("copy")
@@ -912,28 +912,26 @@ TEST_CASE("iterators 2")
json j{1, 3, 2, 4};
auto j_even = json::array();
#if JSON_USE_IMPLICIT_CONVERSIONS
auto it = std::ranges::find_if(j, [](int v) noexcept
{
#if JSON_USE_IMPLICIT_CONVERSIONS
auto it = std::ranges::find_if(j, [](int v) noexcept {
return (v % 2) == 0;
});
#else
auto it = std::ranges::find_if(j, [](const json & j) noexcept
{
#else
auto it = std::ranges::find_if(j, [](const json& j) noexcept {
int v;
j.get_to(v);
return (v % 2) == 0;
});
#endif
#endif
CHECK(*it == 2);
}
}
#endif
#endif
// libstdc++ views don't work with Clang 15 (04/2022)
// libc++ hides limited ranges implementation behind guard macro
#if !(DOCTEST_CLANG && (defined(__GLIBCXX__) || defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)))
#if !(DOCTEST_CLANG && (defined(__GLIBCXX__) || defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)))
SECTION("views")
{
SECTION("reverse")
@@ -947,25 +945,23 @@ TEST_CASE("iterators 2")
SECTION("transform")
{
json j
{
{ "a_key", "a_value"},
{ "b_key", "b_value"},
{ "c_key", "c_value"},
json j{
{"a_key", "a_value"},
{"b_key", "b_value"},
{"c_key", "c_value"},
};
json j_expected{"a_key", "b_key", "c_key"};
auto transformed = j.items() | std::views::transform([](const auto & item)
{
return item.key();
});
auto transformed = j.items() | std::views::transform([](const auto& item) {
return item.key();
});
auto j_transformed = json::array();
std::ranges::copy(transformed, std::back_inserter(j_transformed));
CHECK(j_transformed == j_expected);
}
}
#endif
#endif
}
#endif
}
+18 -30
View File
@@ -11,11 +11,11 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#ifdef JSON_TEST_NO_GLOBAL_UDLS
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
#endif
#include <fstream>
#include "make_test_data_available.hpp"
#include <fstream>
TEST_CASE("JSON patch")
{
@@ -634,7 +634,7 @@ TEST_CASE("JSON patch")
CHECK(target == R"({ "D": "Berlin", "F": "Paris", "GB": "London" })"_json);
// create a diff from two JSONs
json p2 = json::diff(target, source); // NOLINT(readability-suspicious-call-argument)
json p2 = json::diff(target, source); // NOLINT(readability-suspicious-call-argument)
// p2 = [{"op": "delete", "path": "/GB"}]
CHECK(p2 == R"([{"op":"remove","path":"/GB"}])"_json);
}
@@ -1217,76 +1217,64 @@ TEST_CASE("JSON patch")
SECTION("add")
{
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(
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(
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")
{
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(
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(
R"( [{"op": "remove", "path": "/foo/0/bar"}] )"_json
) == R"( {"foo": [{}]} )"_json);
R"( [{"op": "remove", "path": "/foo/0/bar"}] )"_json) == R"( {"foo": [{}]} )"_json);
}
SECTION("replace")
{
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(
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(
R"( [{"op": "replace", "path": "/foo/0/bar", "value": 1}] )"_json
) == R"( {"foo": [{"bar": 1}]} )"_json);
R"( [{"op": "replace", "path": "/foo/0/bar", "value": 1}] )"_json) == R"( {"foo": [{"bar": 1}]} )"_json);
}
SECTION("move")
{
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")
{
CHECK(R"( {"foo": [1, 2, 3]} )"_json.patch(
R"( [{"op": "copy", "from": "/foo/1", "path": "/bar"}] )"_json
) == R"( {"foo": [1, 2, 3], "bar": 2} )"_json);
R"( [{"op": "copy", "from": "/foo/1", "path": "/bar"}] )"_json) == R"( {"foo": [1, 2, 3], "bar": 2} )"_json);
}
SECTION("copy")
{
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")
{
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)
std::ifstream f(filename);
+120 -125
View File
@@ -12,7 +12,7 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#ifdef JSON_TEST_NO_GLOBAL_UDLS
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
#endif
#include <map>
@@ -23,26 +23,32 @@ TEST_CASE("JSON pointers")
SECTION("errors")
{
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("/~~"),
"[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("/~"),
"[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;
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&);
"[json.exception.out_of_range.405] JSON pointer has no parent",
json::out_of_range&);
SECTION("array index error")
{
json v = {1, 2, 3, 4};
json::json_pointer const ptr("/10e");
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&);
}
}
@@ -144,9 +150,11 @@ TEST_CASE("JSON pointers")
// unresolved access
json j_primitive = 1;
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),
"[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")));
}
@@ -206,14 +214,17 @@ TEST_CASE("JSON pointers")
// unescaped access
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
const json j_primitive = 1;
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),
"[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")
@@ -274,13 +285,17 @@ TEST_CASE("JSON pointers")
// error with leading 0
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],
"[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),
"[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),
"[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));
@@ -289,24 +304,32 @@ TEST_CASE("JSON pointers")
// error with incorrect numbers
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,
"[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,
"[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,
"[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,
"[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,
"[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,
"[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&);
"[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";
@@ -335,9 +358,11 @@ TEST_CASE("JSON pointers")
DOCTEST_MSVC_SUPPRESS_WARNING_POP
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,
"[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));
@@ -345,7 +370,8 @@ TEST_CASE("JSON pointers")
CHECK(!j_const.contains("/one"_json_pointer));
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 "-"
j["/-"_json_pointer] = 99;
@@ -353,14 +379,17 @@ TEST_CASE("JSON pointers")
// error when using "-" in const object
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));
// error when using "-" with at
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&);
"[json.exception.out_of_range.402] array index '-' (3) is out of range",
json::out_of_range&);
CHECK(!j_const.contains("/-"_json_pointer));
}
@@ -375,19 +404,23 @@ TEST_CASE("JSON pointers")
// assign to nonexisting index
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));
// assign to nonexisting index (with gap)
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));
// assign to "-"
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&);
"[json.exception.out_of_range.402] array index '-' (3) is out of range",
json::out_of_range&);
CHECK(!j.contains("/-"_json_pointer));
}
}
@@ -395,46 +428,31 @@ TEST_CASE("JSON pointers")
SECTION("flatten")
{
json j =
{
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{
"answer", {
{"everything", 42}
}
},
{"list", {1, 0, 2}},
{
"object", {
{"currency", "USD"},
{"value", 42.99},
{"", "empty string"},
{"/", "slash"},
{"~", "tilde"},
{"~1", "tilde1"}
}
}
};
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {{"everything", 42}}},
{"list", {1, 0, 2}},
{"object", {{"currency", "USD"}, {"value", 42.99}, {"", "empty string"}, {"/", "slash"}, {"~", "tilde"}, {"~1", "tilde1"}}}};
json j_flatten =
{
{"/pi", 3.141},
{"/happy", true},
{"/name", "Niels"},
{"/nothing", nullptr},
{"/answer/everything", 42},
{"/list/0", 1},
{"/list/1", 0},
{"/list/2", 2},
{"/object/currency", "USD"},
{"/object/value", 42.99},
{"/object/", "empty string"},
{"/object/~1", "slash"},
{"/object/~0", "tilde"},
{"/object/~01", "tilde1"}
};
{
{"/pi", 3.141},
{"/happy", true},
{"/name", "Niels"},
{"/nothing", nullptr},
{"/answer/everything", 42},
{"/list/0", 1},
{"/list/1", 0},
{"/list/2", 2},
{"/object/currency", "USD"},
{"/object/value", 42.99},
{"/object/", "empty string"},
{"/object/~1", "slash"},
{"/object/~0", "tilde"},
{"/object/~01", "tilde1"}};
// check if flattened result is as expected
CHECK(j.flatten() == j_flatten);
@@ -444,7 +462,8 @@ TEST_CASE("JSON pointers")
// error for nonobjects
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
#if JSON_DIAGNOSTICS
@@ -456,7 +475,8 @@ TEST_CASE("JSON pointers")
// error for conflicting values
json const j_error = {{"", 42}, {"/foo", 17}};
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
CHECK(j.flatten().unflatten() == j);
@@ -481,8 +501,7 @@ TEST_CASE("JSON pointers")
SECTION("string representation")
{
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);
std::stringstream ss;
@@ -515,29 +534,15 @@ TEST_CASE("JSON pointers")
SECTION("empty, push, pop and parent")
{
const json j =
{
{"", "Hello"},
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{
"answer", {
{"everything", 42}
}
},
{"list", {1, 0, 2}},
{
"object", {
{"currency", "USD"},
{"value", 42.99},
{"", "empty string"},
{"/", "slash"},
{"~", "tilde"},
{"~1", "tilde1"}
}
}
};
{"", "Hello"},
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {{"everything", 42}}},
{"list", {1, 0, 2}},
{"object", {{"currency", "USD"}, {"value", 42.99}, {"", "empty string"}, {"/", "slash"}, {"~", "tilde"}, {"~1", "tilde1"}}}};
// empty json_pointer returns the root JSON-object
auto ptr = ""_json_pointer;
@@ -591,29 +596,15 @@ TEST_CASE("JSON pointers")
SECTION("operators")
{
const json j =
{
{"", "Hello"},
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{
"answer", {
{"everything", 42}
}
},
{"list", {1, 0, 2}},
{
"object", {
{"currency", "USD"},
{"value", 42.99},
{"", "empty string"},
{"/", "slash"},
{"~", "tilde"},
{"~1", "tilde1"}
}
}
};
{"", "Hello"},
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {{"everything", 42}}},
{"list", {1, 0, 2}},
{"object", {{"currency", "USD"}, {"value", 42.99}, {"", "empty string"}, {"/", "slash"}, {"~", "tilde"}, {"~1", "tilde1"}}}};
// empty json_pointer returns the root JSON-object
auto ptr = ""_json_pointer;
@@ -652,7 +643,7 @@ TEST_CASE("JSON pointers")
SECTION("equality comparison")
{
const char* ptr_cpstring = "/foo/bar";
const char ptr_castring[] = "/foo/bar"; // NOLINT(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays)
const char ptr_castring[] = "/foo/bar"; // NOLINT(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays)
std::string ptr_string{"/foo/bar"};
auto ptr1 = json::json_pointer(ptr_string);
auto ptr2 = json::json_pointer(ptr_string);
@@ -687,13 +678,17 @@ TEST_CASE("JSON pointers")
SECTION("exceptions")
{
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,
"[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 == "/~~",
"[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,
"[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&);
}
}
@@ -708,7 +703,7 @@ TEST_CASE("JSON pointers")
// build with C++20
// JSON_HAS_CPP_20
#if JSON_HAS_THREE_WAY_COMPARISON
CHECK((ptr1 <=> ptr2) == std::strong_ordering::less); // *NOPAD*
CHECK((ptr1 <= > ptr2) == std::strong_ordering::less); // *NOPAD*
CHECK(ptr2 > ptr1);
#endif
}
-1
View File
@@ -26,4 +26,3 @@ TEST_CASE("tests on very large JSONs")
CHECK_NOTHROW(_ = nlohmann::json::parse(s));
}
}
+1 -1
View File
@@ -11,7 +11,7 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#ifdef JSON_TEST_NO_GLOBAL_UDLS
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
#endif
TEST_CASE("JSON Merge Patch")
+4 -6
View File
@@ -21,12 +21,10 @@ TEST_CASE("version information")
CHECK(j["copyright"] == "(C) 2013-2023 Niels Lohmann");
CHECK(j["url"] == "https://github.com/nlohmann/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.at("compiler").find("family") != j.at("compiler").end());
+2 -4
View File
@@ -637,10 +637,8 @@ TEST_CASE("modifiers")
{
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",
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",
json::invalid_iterator&);
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&);
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&);
}
}
+355 -286
View File
@@ -11,23 +11,23 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#ifdef JSON_TEST_NO_GLOBAL_UDLS
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
#endif
#include "make_test_data_available.hpp"
#include "test_utils.hpp"
#include <fstream>
#include <sstream>
#include <iomanip>
#include <limits>
#include <set>
#include "make_test_data_available.hpp"
#include "test_utils.hpp"
#include <sstream>
namespace
{
namespace {
class SaxCountdown
{
public:
explicit SaxCountdown(const int count) : events_left(count)
explicit SaxCountdown(const int count)
: events_left(count)
{}
bool null()
@@ -90,7 +90,7 @@ class SaxCountdown
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;
}
@@ -98,7 +98,7 @@ class SaxCountdown
private:
int events_left = 0;
};
} // namespace
} // namespace
TEST_CASE("MessagePack")
{
@@ -168,10 +168,8 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_integer());
// create expected byte vector
std::vector<uint8_t> const expected
{
static_cast<uint8_t>(i)
};
std::vector<uint8_t> const expected{
static_cast<uint8_t>(i)};
// compare result + size
const auto result = json::to_msgpack(j);
@@ -231,8 +229,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_integer());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xcc,
static_cast<uint8_t>(i),
};
@@ -267,8 +264,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_integer());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xcd,
static_cast<uint8_t>((i >> 8) & 0xff),
static_cast<uint8_t>(i & 0xff),
@@ -293,9 +289,11 @@ TEST_CASE("MessagePack")
SECTION("65536..4294967295 (int 32)")
{
for (uint32_t i :
{
65536u, 77777u, 1048576u, 4294967295u
})
{
65536u,
77777u,
1048576u,
4294967295u})
{
CAPTURE(i)
@@ -307,8 +305,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_integer());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xce,
static_cast<uint8_t>((i >> 24) & 0xff),
static_cast<uint8_t>((i >> 16) & 0xff),
@@ -338,9 +335,9 @@ TEST_CASE("MessagePack")
SECTION("4294967296..9223372036854775807 (int 64)")
{
for (uint64_t i :
{
4294967296LU, 9223372036854775807LU
})
{
4294967296LU,
9223372036854775807LU})
{
CAPTURE(i)
@@ -352,8 +349,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_integer());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xcf,
static_cast<uint8_t>((i >> 070) & 0xff),
static_cast<uint8_t>((i >> 060) & 0xff),
@@ -401,8 +397,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_integer());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xd0,
static_cast<uint8_t>(i),
};
@@ -451,8 +446,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_integer());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xd1,
static_cast<uint8_t>((i >> 8) & 0xff),
static_cast<uint8_t>(i & 0xff),
@@ -476,14 +470,13 @@ TEST_CASE("MessagePack")
SECTION("-32769..-2147483648")
{
std::vector<int32_t> const numbers
{
std::vector<int32_t> const numbers{
-32769,
-65536,
-77777,
-1048576,
-2147483648LL,
};
-65536,
-77777,
-1048576,
-2147483648LL,
};
for (auto i : numbers)
{
CAPTURE(i)
@@ -495,8 +488,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_integer());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xd2,
static_cast<uint8_t>((i >> 24) & 0xff),
static_cast<uint8_t>((i >> 16) & 0xff),
@@ -525,8 +517,7 @@ TEST_CASE("MessagePack")
SECTION("-9223372036854775808..-2147483649 (int 64)")
{
std::vector<int64_t> const numbers
{
std::vector<int64_t> const numbers{
(std::numeric_limits<int64_t>::min)(),
-2147483649LL,
};
@@ -541,8 +532,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_integer());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xd3,
static_cast<uint8_t>((i >> 070) & 0xff),
static_cast<uint8_t>((i >> 060) & 0xff),
@@ -622,8 +612,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_unsigned());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xcc,
static_cast<uint8_t>(i),
};
@@ -657,8 +646,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_unsigned());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xcd,
static_cast<uint8_t>((i >> 8) & 0xff),
static_cast<uint8_t>(i & 0xff),
@@ -683,9 +671,11 @@ TEST_CASE("MessagePack")
SECTION("65536..4294967295 (uint 32)")
{
for (const uint32_t i :
{
65536u, 77777u, 1048576u, 4294967295u
})
{
65536u,
77777u,
1048576u,
4294967295u})
{
CAPTURE(i)
@@ -696,8 +686,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_unsigned());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xce,
static_cast<uint8_t>((i >> 24) & 0xff),
static_cast<uint8_t>((i >> 16) & 0xff),
@@ -727,9 +716,9 @@ TEST_CASE("MessagePack")
SECTION("4294967296..18446744073709551615 (uint 64)")
{
for (const uint64_t i :
{
4294967296LU, 18446744073709551615LU
})
{
4294967296LU,
18446744073709551615LU})
{
CAPTURE(i)
@@ -740,8 +729,7 @@ TEST_CASE("MessagePack")
CHECK(j.is_number_unsigned());
// create expected byte vector
std::vector<uint8_t> const expected
{
std::vector<uint8_t> const expected{
0xcf,
static_cast<uint8_t>((i >> 070) & 0xff),
static_cast<uint8_t>((i >> 060) & 0xff),
@@ -784,9 +772,16 @@ TEST_CASE("MessagePack")
double const v = 3.1415925;
json const j = v;
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);
CHECK(result == expected);
@@ -801,9 +796,12 @@ TEST_CASE("MessagePack")
double const v = 1.0;
json const j = v;
std::vector<uint8_t> const expected =
{
0xca, 0x3f, 0x80, 0x00, 0x00
};
{
0xca,
0x3f,
0x80,
0x00,
0x00};
const auto result = json::to_msgpack(j);
CHECK(result == expected);
@@ -818,9 +816,12 @@ TEST_CASE("MessagePack")
double const v = 128.1280059814453125;
json const j = v;
std::vector<uint8_t> const expected =
{
0xca, 0x43, 0x00, 0x20, 0xc5
};
{
0xca,
0x43,
0x00,
0x20,
0xc5};
const auto result = json::to_msgpack(j);
CHECK(result == expected);
@@ -838,12 +839,39 @@ TEST_CASE("MessagePack")
{
// explicitly enumerate the first byte for all 32 strings
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)
{
@@ -915,9 +943,13 @@ TEST_CASE("MessagePack")
SECTION("N = 256..65535")
{
for (size_t N :
{
256u, 999u, 1025u, 3333u, 2048u, 65535u
})
{
256u,
999u,
1025u,
3333u,
2048u,
65535u})
{
CAPTURE(N)
@@ -948,9 +980,10 @@ TEST_CASE("MessagePack")
SECTION("N = 65536..4294967295")
{
for (size_t N :
{
65536u, 77777u, 1048576u
})
{
65536u,
77777u,
1048576u})
{
CAPTURE(N)
@@ -1034,10 +1067,10 @@ TEST_CASE("MessagePack")
SECTION("array 16")
{
json j(16, nullptr);
std::vector<uint8_t> expected(j.size() + 3, 0xc0); // all null
expected[0] = 0xdc; // array 16
expected[1] = 0x00; // size (0x0010), byte 0
expected[2] = 0x10; // size (0x0010), byte 1
std::vector<uint8_t> expected(j.size() + 3, 0xc0); // all null
expected[0] = 0xdc; // array 16
expected[1] = 0x00; // size (0x0010), byte 0
expected[2] = 0x10; // size (0x0010), byte 1
const auto result = json::to_msgpack(j);
CHECK(result == expected);
@@ -1049,12 +1082,12 @@ TEST_CASE("MessagePack")
SECTION("array 32")
{
json j(65536, nullptr);
std::vector<uint8_t> expected(j.size() + 5, 0xc0); // all null
expected[0] = 0xdd; // array 32
expected[1] = 0x00; // size (0x00100000), byte 0
expected[2] = 0x01; // size (0x00100000), byte 1
expected[3] = 0x00; // size (0x00100000), byte 2
expected[4] = 0x00; // size (0x00100000), byte 3
std::vector<uint8_t> expected(j.size() + 5, 0xc0); // all null
expected[0] = 0xdd; // array 32
expected[1] = 0x00; // size (0x00100000), byte 0
expected[2] = 0x01; // size (0x00100000), byte 1
expected[3] = 0x00; // size (0x00100000), byte 2
expected[4] = 0x00; // size (0x00100000), byte 3
const auto result = json::to_msgpack(j);
//CHECK(result == expected);
@@ -1101,9 +1134,17 @@ TEST_CASE("MessagePack")
{
json const j = json::parse(R"({"a": {"b": {"c": {}}}})");
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);
CHECK(result == expected);
@@ -1126,10 +1167,10 @@ TEST_CASE("MessagePack")
// pairs are made. We therefore only check the prefix (type and
// size) and the overall size. The rest is then handled in the
// roundtrip check.
CHECK(result.size() == 67); // 1 type, 2 size, 16*4 content
CHECK(result[0] == 0xde); // map 16
CHECK(result[1] == 0x00); // byte 0 of size (0x0010)
CHECK(result[2] == 0x10); // byte 1 of size (0x0010)
CHECK(result.size() == 67); // 1 type, 2 size, 16*4 content
CHECK(result[0] == 0xde); // map 16
CHECK(result[1] == 0x00); // byte 0 of size (0x0010)
CHECK(result[2] == 0x10); // byte 1 of size (0x0010)
// roundtrip
CHECK(json::from_msgpack(result) == j);
@@ -1155,12 +1196,12 @@ TEST_CASE("MessagePack")
// pairs are made. We therefore only check the prefix (type and
// size) and the overall size. The rest is then handled in the
// roundtrip check.
CHECK(result.size() == 458757); // 1 type, 4 size, 65536*7 content
CHECK(result[0] == 0xdf); // map 32
CHECK(result[1] == 0x00); // byte 0 of size (0x00010000)
CHECK(result[2] == 0x01); // byte 1 of size (0x00010000)
CHECK(result[3] == 0x00); // byte 2 of size (0x00010000)
CHECK(result[4] == 0x00); // byte 3 of size (0x00010000)
CHECK(result.size() == 458757); // 1 type, 4 size, 65536*7 content
CHECK(result[0] == 0xdf); // map 32
CHECK(result[1] == 0x00); // byte 0 of size (0x00010000)
CHECK(result[2] == 0x01); // byte 1 of size (0x00010000)
CHECK(result[3] == 0x00); // byte 2 of size (0x00010000)
CHECK(result[4] == 0x00); // byte 3 of size (0x00010000)
// roundtrip
CHECK(json::from_msgpack(result) == j);
@@ -1245,9 +1286,13 @@ TEST_CASE("MessagePack")
SECTION("N = 256..65535")
{
for (std::size_t N :
{
256u, 999u, 1025u, 3333u, 2048u, 65535u
})
{
256u,
999u,
1025u,
3333u,
2048u,
65535u})
{
CAPTURE(N)
@@ -1281,9 +1326,10 @@ TEST_CASE("MessagePack")
SECTION("N = 65536..4294967295")
{
for (std::size_t N :
{
65536u, 77777u, 1048576u
})
{
65536u,
77777u,
1048576u})
{
CAPTURE(N)
@@ -1357,9 +1403,13 @@ TEST_CASE("MessagePack")
SECTION("N = 256..65535")
{
for (std::size_t N :
{
256u, 999u, 1025u, 3333u, 2048u, 65535u
})
{
256u,
999u,
1025u,
3333u,
2048u,
65535u})
{
CAPTURE(N)
@@ -1390,9 +1440,10 @@ TEST_CASE("MessagePack")
SECTION("N = 65536..4294967295")
{
for (std::size_t N :
{
65536u, 77777u, 1048576u
})
{
65536u,
77777u,
1048576u})
{
CAPTURE(N)
@@ -1445,45 +1496,65 @@ TEST_CASE("MessagePack")
json _;
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0x87})),
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input", json::parse_error&);
"[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(std::vector<uint8_t>({0xcc})),
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input",
json::parse_error&);
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcd})),
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input",
json::parse_error&);
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})),
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input",
json::parse_error&);
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xce})),
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input",
json::parse_error&);
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})),
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input",
json::parse_error&);
CHECK_THROWS_WITH_AS(_ = json::from_msgpack(std::vector<uint8_t>({0xce, 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&);
"[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>({0xce, 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&);
"[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})),
"[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
"[json.exception.parse_error.110] parse error at byte 2: 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})),
"[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
"[json.exception.parse_error.110] parse error at byte 3: 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})),
"[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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&);
"[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>({0xcc}), true, false).is_discarded());
@@ -1519,10 +1590,9 @@ TEST_CASE("MessagePack")
SECTION("all unsupported bytes")
{
for (auto byte :
{
// never used
0xc1
})
{
// never used
0xc1})
{
json _;
CHECK_THROWS_AS(_ = json::from_msgpack(std::vector<uint8_t>({static_cast<uint8_t>(byte)})), json::parse_error&);
@@ -1636,7 +1706,7 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip())
exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/3.json");
exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/4.json");
exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/5.json");
exclude_packed.insert(TEST_DATA_DIRECTORY "/json_testsuite/sample.json"); // kills AppVeyor
exclude_packed.insert(TEST_DATA_DIRECTORY "/json_testsuite/sample.json"); // kills AppVeyor
exclude_packed.insert(TEST_DATA_DIRECTORY "/json_tests/pass1.json");
exclude_packed.insert(TEST_DATA_DIRECTORY "/regression/working_file.json");
exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object.json");
@@ -1647,153 +1717,152 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip())
exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_string_unicode.json");
for (std::string filename :
{
TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json",
TEST_DATA_DIRECTORY "/json.org/1.json",
TEST_DATA_DIRECTORY "/json.org/2.json",
TEST_DATA_DIRECTORY "/json.org/3.json",
TEST_DATA_DIRECTORY "/json.org/4.json",
TEST_DATA_DIRECTORY "/json.org/5.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip01.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip02.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip03.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip04.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip05.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip06.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip07.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip08.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip09.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip10.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip11.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip12.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip13.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip14.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip15.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip16.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip17.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip18.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip19.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip20.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip21.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip22.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip23.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip24.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip25.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip26.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip27.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip28.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip29.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip30.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip31.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip32.json",
TEST_DATA_DIRECTORY "/json_testsuite/sample.json", // kills AppVeyor
TEST_DATA_DIRECTORY "/json_tests/pass1.json",
TEST_DATA_DIRECTORY "/json_tests/pass2.json",
TEST_DATA_DIRECTORY "/json_tests/pass3.json",
TEST_DATA_DIRECTORY "/regression/floats.json",
TEST_DATA_DIRECTORY "/regression/signed_ints.json",
TEST_DATA_DIRECTORY "/regression/unsigned_ints.json",
TEST_DATA_DIRECTORY "/regression/working_file.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.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_false.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_heterogeneous.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_null.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_1_and_newline.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_leading_space.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_several_null.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_trailing_space.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_0e+1.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_0e1.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_after_space.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_double_huge_neg_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_int_with_exp.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_minus_zero.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_int.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_one.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_zero.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e_neg_exp.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e_pos_exp.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_exponent.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_neg_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_pos_exponent.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_underflow.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_simple_int.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_simple_real.json",
//TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_too_big_neg_int.json",
//TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_too_big_pos_int.json",
//TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_very_big_negative_int.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_basic.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_duplicated_key.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_duplicated_key_and_value.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_empty.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_empty_key.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_escaped_null_in_key.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_extreme_numbers.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_long_strings.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_simple.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_string_unicode.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_with_newlines.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_UTF-16_Surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pair.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pairs.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_allowed_escapes.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_backslash_and_u_escaped_zero.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_backslash_doublequotes.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_comments.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_double_escape_a.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_double_escape_n.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_escaped_control_character.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_escaped_noncharacter.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_in_array.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_in_array_with_leading_space.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_last_surrogates_1_and_2.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_newline_uescaped.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_null_escape.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_one-byte-utf-8.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_pi.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_simple_ascii.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_space.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_three-byte-utf-8.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_two-byte-utf-8.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_u+2028_line_sep.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_u+2029_par_sep.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_uEscape.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unescaped_char_delete.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicodeEscapedBackslash.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_2.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_escaped_double_quote.json",
// TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_utf16.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_utf8.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_with_del_character.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_false.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_int.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_negative_real.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_null.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_string.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_true.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_true_in_array.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_whitespace_array.json"
})
{
TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json",
TEST_DATA_DIRECTORY "/json.org/1.json",
TEST_DATA_DIRECTORY "/json.org/2.json",
TEST_DATA_DIRECTORY "/json.org/3.json",
TEST_DATA_DIRECTORY "/json.org/4.json",
TEST_DATA_DIRECTORY "/json.org/5.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip01.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip02.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip03.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip04.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip05.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip06.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip07.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip08.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip09.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip10.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip11.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip12.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip13.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip14.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip15.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip16.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip17.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip18.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip19.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip20.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip21.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip22.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip23.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip24.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip25.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip26.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip27.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip28.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip29.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip30.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip31.json",
TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip32.json",
TEST_DATA_DIRECTORY "/json_testsuite/sample.json", // kills AppVeyor
TEST_DATA_DIRECTORY "/json_tests/pass1.json",
TEST_DATA_DIRECTORY "/json_tests/pass2.json",
TEST_DATA_DIRECTORY "/json_tests/pass3.json",
TEST_DATA_DIRECTORY "/regression/floats.json",
TEST_DATA_DIRECTORY "/regression/signed_ints.json",
TEST_DATA_DIRECTORY "/regression/unsigned_ints.json",
TEST_DATA_DIRECTORY "/regression/working_file.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.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_false.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_heterogeneous.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_null.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_1_and_newline.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_leading_space.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_several_null.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_trailing_space.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_0e+1.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_0e1.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_after_space.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_double_huge_neg_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_int_with_exp.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_minus_zero.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_int.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_one.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_zero.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e_neg_exp.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e_pos_exp.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_exponent.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_neg_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_pos_exponent.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_underflow.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_simple_int.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_simple_real.json",
//TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_too_big_neg_int.json",
//TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_too_big_pos_int.json",
//TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_very_big_negative_int.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_basic.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_duplicated_key.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_duplicated_key_and_value.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_empty.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_empty_key.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_escaped_null_in_key.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_extreme_numbers.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_long_strings.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_simple.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_string_unicode.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_with_newlines.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_UTF-16_Surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pair.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pairs.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_allowed_escapes.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_backslash_and_u_escaped_zero.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_backslash_doublequotes.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_comments.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_double_escape_a.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_double_escape_n.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_escaped_control_character.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_escaped_noncharacter.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_in_array.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_in_array_with_leading_space.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_last_surrogates_1_and_2.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_newline_uescaped.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_null_escape.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_one-byte-utf-8.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_pi.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_simple_ascii.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_space.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_three-byte-utf-8.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_two-byte-utf-8.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_u+2028_line_sep.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_u+2029_par_sep.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_uEscape.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unescaped_char_delete.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicodeEscapedBackslash.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_2.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_escaped_double_quote.json",
// TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_utf16.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_utf8.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_with_del_character.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_false.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_int.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_negative_real.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_null.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_string.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_true.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_true_in_array.json",
TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_whitespace_array.json"})
{
CAPTURE(filename)
+10 -13
View File
@@ -8,9 +8,9 @@
#include "doctest_compatibility.h"
#include <nlohmann/json.hpp>
#include <exception>
#include <iostream>
#include <nlohmann/json.hpp>
struct Foo
{
@@ -18,9 +18,8 @@ struct Foo
int b;
};
namespace nlohmann
{
template <>
namespace nlohmann {
template<>
struct adl_serializer<Foo>
{
static void to_json(json& j, Foo const& f)
@@ -42,16 +41,16 @@ struct adl_serializer<Foo>
}
}
};
} // namespace nlohmann
} // namespace nlohmann
TEST_CASE("check_for_mem_leak_on_adl_to_json-1")
{
try
{
const nlohmann::json j = Foo {1, 0};
const nlohmann::json j = Foo{1, 0};
std::cout << j.dump() << "\n";
}
catch (...) // NOLINT(bugprone-empty-catch)
catch (...) // NOLINT(bugprone-empty-catch)
{
// just ignore the exception in this POC
}
@@ -61,10 +60,10 @@ TEST_CASE("check_for_mem_leak_on_adl_to_json-2")
{
try
{
const nlohmann::json j = Foo {1, 1};
const nlohmann::json j = Foo{1, 1};
std::cout << j.dump() << "\n";
}
catch (...) // NOLINT(bugprone-empty-catch)
catch (...) // NOLINT(bugprone-empty-catch)
{
// just ignore the exception in this POC
}
@@ -74,13 +73,11 @@ TEST_CASE("check_for_mem_leak_on_adl_to_json-2")
{
try
{
const nlohmann::json j = Foo {1, 2};
const nlohmann::json j = Foo{1, 2};
std::cout << j.dump() << "\n";
}
catch (...) // NOLINT(bugprone-empty-catch)
catch (...) // NOLINT(bugprone-empty-catch)
{
// just ignore the exception in this POC
}
}
+12 -9
View File
@@ -16,12 +16,15 @@ DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept")
using nlohmann::json;
namespace
namespace {
enum test
{
enum test {};
};
struct pod {};
struct pod_bis {};
struct pod
{};
struct pod_bis
{};
void to_json(json& /*unused*/, pod /*unused*/) noexcept;
void to_json(json& /*unused*/, pod_bis /*unused*/);
@@ -45,15 +48,15 @@ static_assert(noexcept(json(pod{})), "");
static_assert(noexcept(std::declval<json>().get<pod>()), "");
static_assert(!noexcept(std::declval<json>().get<pod_bis>()), "");
static_assert(noexcept(json(pod{})), "");
} // namespace
} // namespace
TEST_CASE("noexcept")
{
// silence -Wunneeded-internal-declaration errors
static_cast<void>(static_cast<void(*)(json&, pod)>(&to_json));
static_cast<void>(static_cast<void(*)(json&, pod_bis)>(&to_json));
static_cast<void>(static_cast<void(*)(const json&, pod)>(&from_json));
static_cast<void>(static_cast<void(*)(const json&, pod_bis)>(&from_json));
static_cast<void>(static_cast<void (*)(json&, pod)>(&to_json));
static_cast<void>(static_cast<void (*)(json&, pod_bis)>(&to_json));
static_cast<void>(static_cast<void (*)(const json&, pod)>(&from_json));
static_cast<void>(static_cast<void (*)(const json&, pod_bis)>(&from_json));
SECTION("nothrow-copy-constructible exceptions")
{
+8 -8
View File
@@ -45,11 +45,11 @@ TEST_CASE("ordered_json")
CHECK(oj.dump() == "{\"element3\":3,\"element2\":2}");
// There are no dup keys cause constructor calls emplace...
json const multi {{"z", 1}, {"m", 2}, {"m", 3}, {"y", 4}, {"m", 5}};
json const multi{{"z", 1}, {"m", 2}, {"m", 3}, {"y", 4}, {"m", 5}};
CHECK(multi.size() == 3);
CHECK(multi.dump() == "{\"m\":2,\"y\":4,\"z\":1}");
ordered_json multi_ordered {{"z", 1}, {"m", 2}, {"m", 3}, {"y", 4}, {"m", 5}};
ordered_json multi_ordered{{"z", 1}, {"m", 2}, {"m", 3}, {"y", 4}, {"m", 5}};
CHECK(multi_ordered.size() == 3);
CHECK(multi_ordered.dump() == "{\"z\":1,\"m\":2,\"y\":4}");
CHECK(multi_ordered.erase("m") == 1);
@@ -57,15 +57,15 @@ TEST_CASE("ordered_json")
// Ranged insert test.
// It seems that values shouldn't be overwritten. Only new values are added
json j1 {{"c", 1}, {"b", 2}, {"a", 3}};
const json j2 {{"c", 77}, {"d", 42}, {"a", 4}};
j1.insert( j2.cbegin(), j2.cend() );
json j1{{"c", 1}, {"b", 2}, {"a", 3}};
const json j2{{"c", 77}, {"d", 42}, {"a", 4}};
j1.insert(j2.cbegin(), j2.cend());
CHECK(j1.size() == 4);
CHECK(j1.dump() == "{\"a\":3,\"b\":2,\"c\":1,\"d\":42}");
ordered_json oj1 {{"c", 1}, {"b", 2}, {"a", 3}};
const ordered_json oj2 {{"c", 77}, {"d", 42}, {"a", 4}};
oj1.insert( oj2.cbegin(), oj2.cend() );
ordered_json oj1{{"c", 1}, {"b", 2}, {"a", 3}};
const ordered_json oj2{{"c", 77}, {"d", 42}, {"a", 4}};
oj1.insert(oj2.cbegin(), oj2.cend());
CHECK(oj1.size() == 4);
CHECK(oj1.dump() == "{\"c\":1,\"b\":2,\"a\":3,\"d\":42}");
}
+7 -7
View File
@@ -17,24 +17,24 @@ TEST_CASE("ordered_map")
{
SECTION("constructor from iterator range")
{
std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
std::map<std::string, std::string> m{{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
ordered_map<std::string, std::string> const om(m.begin(), m.end());
CHECK(om.size() == 3);
}
SECTION("copy assignment")
{
std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
std::map<std::string, std::string> m{{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
ordered_map<std::string, std::string> om(m.begin(), m.end());
const auto com = om;
om.clear(); // silence a warning by forbidding having "const auto& com = om;"
om.clear(); // silence a warning by forbidding having "const auto& com = om;"
CHECK(com.size() == 3);
}
}
SECTION("at")
{
std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
std::map<std::string, std::string> m{{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
ordered_map<std::string, std::string> om(m.begin(), m.end());
const auto com = om;
@@ -67,7 +67,7 @@ TEST_CASE("ordered_map")
SECTION("operator[]")
{
std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
std::map<std::string, std::string> m{{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
ordered_map<std::string, std::string> om(m.begin(), m.end());
const auto com = om;
@@ -280,8 +280,8 @@ TEST_CASE("ordered_map")
SECTION("const value_type&")
{
ordered_map<std::string, std::string>::value_type const vt1 {"eins", "1"};
ordered_map<std::string, std::string>::value_type const vt4 {"vier", "four"};
ordered_map<std::string, std::string>::value_type const vt1{"eins", "1"};
ordered_map<std::string, std::string>::value_type const vt4{"vier", "four"};
auto res1 = om.insert(vt1);
CHECK(res1.first == om.begin());
+38 -48
View File
@@ -11,18 +11,18 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#ifdef JSON_TEST_NO_GLOBAL_UDLS
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
#endif
#include <deque>
#include <forward_list>
#include <iomanip>
#include <iostream>
#include <list>
#include <set>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
#include <iostream>
#include <sstream>
#include <iomanip>
// local variable is initialized but not referenced
DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
@@ -55,31 +55,21 @@ TEST_CASE("README" * doctest::skip())
j["answer"]["everything"] = 42;
// add an array that is stored as std::vector (using an initializer list)
j["list"] = { 1, 0, 2 };
j["list"] = {1, 0, 2};
// add another object (using an initializer list of pairs)
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)
json const j2 =
{
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{
"answer", {
{"everything", 42}
}
},
{"list", {1, 0, 2}},
{
"object", {
{"currency", "USD"},
{"value", 42.99}
}
}
};
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {{"everything", 42}}},
{"list", {1, 0, 2}},
{"object", {{"currency", "USD"}, {"value", 42.99}}}};
}
{
@@ -94,7 +84,7 @@ TEST_CASE("README" * doctest::skip())
CHECK(empty_object_explicit.is_object());
// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]]
json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });
json array_not_object = json::array({{"currency", "USD"}, {"value", 42.99}});
CHECK(array_not_object.is_array());
CHECK(array_not_object.size() == 2);
CHECK(array_not_object[0].is_array());
@@ -103,7 +93,7 @@ TEST_CASE("README" * doctest::skip())
{
// create object from string literal
json const j = "{ \"happy\": true, \"pi\": 3.141 }"_json; // NOLINT(modernize-raw-string-literal)
json const j = "{ \"happy\": true, \"pi\": 3.141 }"_json; // NOLINT(modernize-raw-string-literal)
// or even nicer with a raw string literal
auto j2 = R"({
@@ -115,17 +105,17 @@ TEST_CASE("README" * doctest::skip())
auto j3 = json::parse(R"({"happy": true, "pi": 3.141})");
// explicit conversion to string
std::string const s = j.dump(); // {\"happy\":true,\"pi\":3.141}
std::string const s = j.dump(); // {\"happy\":true,\"pi\":3.141}
// serialization with pretty printing
// pass in the amount of spaces to indent
std::cout << j.dump(4) << std::endl; // NOLINT(performance-avoid-endl)
std::cout << j.dump(4) << std::endl; // NOLINT(performance-avoid-endl)
// {
// "happy": true,
// "pi": 3.141
// }
std::cout << std::setw(2) << j << std::endl; // NOLINT(performance-avoid-endl)
std::cout << std::setw(2) << j << std::endl; // NOLINT(performance-avoid-endl)
}
{
@@ -140,7 +130,7 @@ TEST_CASE("README" * doctest::skip())
CHECK(x == true);
// iterate the array
for (json::iterator it = j.begin(); it != j.end(); ++it) // NOLINT(modernize-loop-convert)
for (json::iterator it = j.begin(); it != j.end(); ++it) // NOLINT(modernize-loop-convert)
{
std::cout << *it << '\n';
}
@@ -178,58 +168,58 @@ TEST_CASE("README" * doctest::skip())
}
{
std::vector<int> const c_vector {1, 2, 3, 4};
std::vector<int> const c_vector{1, 2, 3, 4};
json const j_vec(c_vector);
// [1, 2, 3, 4]
std::deque<float> const c_deque {1.2f, 2.3f, 3.4f, 5.6f};
std::deque<float> const c_deque{1.2f, 2.3f, 3.4f, 5.6f};
json const j_deque(c_deque);
// [1.2, 2.3, 3.4, 5.6]
std::list<bool> const c_list {true, true, false, true};
std::list<bool> const c_list{true, true, false, true};
json const j_list(c_list);
// [true, true, false, true]
std::forward_list<int64_t> const c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};
std::forward_list<int64_t> const c_flist{12345678909876, 23456789098765, 34567890987654, 45678909876543};
json const j_flist(c_flist);
// [12345678909876, 23456789098765, 34567890987654, 45678909876543]
std::array<unsigned long, 4> const c_array {{1, 2, 3, 4}};
std::array<unsigned long, 4> const c_array{{1, 2, 3, 4}};
json const j_array(c_array);
// [1, 2, 3, 4]
std::set<std::string> const c_set {"one", "two", "three", "four", "one"};
json const j_set(c_set); // only one entry for "one" is used
std::set<std::string> const c_set{"one", "two", "three", "four", "one"};
json const j_set(c_set); // only one entry for "one" is used
// ["four", "one", "three", "two"]
std::unordered_set<std::string> const c_uset {"one", "two", "three", "four", "one"};
json const j_uset(c_uset); // only one entry for "one" is used
std::unordered_set<std::string> const c_uset{"one", "two", "three", "four", "one"};
json const j_uset(c_uset); // only one entry for "one" is used
// maybe ["two", "three", "four", "one"]
std::multiset<std::string> const c_mset {"one", "two", "one", "four"};
json const j_mset(c_mset); // both entries for "one" are used
std::multiset<std::string> const c_mset{"one", "two", "one", "four"};
json const j_mset(c_mset); // both entries for "one" are used
// maybe ["one", "two", "one", "four"]
std::unordered_multiset<std::string> const c_umset {"one", "two", "one", "four"};
json const j_umset(c_umset); // both entries for "one" are used
std::unordered_multiset<std::string> const c_umset{"one", "two", "one", "four"};
json const j_umset(c_umset); // both entries for "one" are used
// maybe ["one", "two", "one", "four"]
}
{
std::map<std::string, int> const c_map { {"one", 1}, {"two", 2}, {"three", 3} };
std::map<std::string, int> const c_map{{"one", 1}, {"two", 2}, {"three", 3}};
json const j_map(c_map);
// {"one": 1, "two": 2, "three": 3}
std::unordered_map<const char*, float> const c_umap { {"one", 1.2f}, {"two", 2.3f}, {"three", 3.4f} };
std::unordered_map<const char*, float> const c_umap{{"one", 1.2f}, {"two", 2.3f}, {"three", 3.4f}};
json const j_umap(c_umap);
// {"one": 1.2, "two": 2.3, "three": 3.4}
std::multimap<std::string, bool> const c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
json const j_mmap(c_mmap); // only one entry for key "three" is used
std::multimap<std::string, bool> const c_mmap{{"one", true}, {"two", true}, {"three", false}, {"three", true}};
json const j_mmap(c_mmap); // only one entry for key "three" is used
// maybe {"one": true, "two": true, "three": true}
std::unordered_multimap<std::string, bool> const c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
json const j_ummap(c_ummap); // only one entry for key "three" is used
std::unordered_multimap<std::string, bool> const c_ummap{{"one", true}, {"two", true}, {"three", false}, {"three", true}};
json const j_ummap(c_ummap); // only one entry for key "three" is used
// maybe {"one": true, "two": true, "three": true}
}
+73 -45
View File
@@ -15,18 +15,12 @@ TEST_CASE("reference access")
{
// create a JSON value with different types
const json json_types =
{
{"boolean", true},
{
"number", {
{"integer", 42},
{"floating-point", 17.23}
}
},
{"string", "Hello, world!"},
{"array", {1, 2, 3, 4, 5}},
{"null", nullptr}
};
{"boolean", true},
{"number", {{"integer", 42}, {"floating-point", 17.23}}},
{"string", "Hello, world!"},
{"array", {1, 2, 3, 4, 5}},
{"null", nullptr}};
SECTION("reference access to object_t")
{
@@ -45,17 +39,23 @@ TEST_CASE("reference access")
// check if mismatching references throw correctly
CHECK_NOTHROW(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 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&>(),
"[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&>(),
"[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&>(),
"[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&>(),
"[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&>(),
"[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")
@@ -88,18 +88,24 @@ TEST_CASE("reference access")
// 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 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_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&>(),
"[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&>(),
"[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&>(),
"[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&>(),
"[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")
@@ -118,18 +124,24 @@ TEST_CASE("reference access")
// 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 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&>(),
"[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_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&>(),
"[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&>(),
"[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&>(),
"[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")
@@ -148,18 +160,24 @@ TEST_CASE("reference access")
// 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 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&>(),
"[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&>(),
"[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_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&>(),
"[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&>(),
"[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")
@@ -178,18 +196,24 @@ TEST_CASE("reference access")
// 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&);
"[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&>(),
"[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&>(),
"[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&>(),
"[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_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&>(),
"[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")
@@ -208,13 +232,17 @@ TEST_CASE("reference access")
// 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&);
"[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&>(),
"[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&>(),
"[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&>(),
"[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&>(),
// "[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&>());
File diff suppressed because it is too large Load Diff
+73 -77
View File
@@ -23,7 +23,7 @@
using json = nlohmann::json;
using ordered_json = nlohmann::ordered_json;
#ifdef JSON_TEST_NO_GLOBAL_UDLS
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
#endif
#include <cstdio>
@@ -55,8 +55,7 @@ using float_json = nlohmann::basic_json<std::map, std::vector, std::string, bool
/////////////////////////////////////////////////////////////////////
// for #1647
/////////////////////////////////////////////////////////////////////
namespace
{
namespace {
struct NonDefaultFromJsonStruct
{};
@@ -73,10 +72,10 @@ enum class for_1647
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays): this is a false positive
NLOHMANN_JSON_SERIALIZE_ENUM(for_1647,
{
{for_1647::one, "one"},
{for_1647::two, "two"},
})
{
{for_1647::one, "one"},
{for_1647::two, "two"},
})
} // namespace
/////////////////////////////////////////////////////////////////////
@@ -87,8 +86,8 @@ struct Data
{
Data() = default;
Data(std::string a_, std::string b_)
: a(std::move(a_))
, b(std::move(b_))
: a(std::move(a_))
, b(std::move(b_))
{}
std::string a{};
std::string b{};
@@ -112,8 +111,7 @@ bool operator==(Data const& lhs, Data const& rhs)
// return !(lhs == rhs);
//}
namespace nlohmann
{
namespace nlohmann {
template<>
struct adl_serializer<NonDefaultFromJsonStruct>
{
@@ -141,13 +139,12 @@ struct NotSerializableData
struct NonDefaultConstructible
{
explicit NonDefaultConstructible(int a)
: x(a)
: x(a)
{}
int x;
};
namespace nlohmann
{
namespace nlohmann {
template<>
struct adl_serializer<NonDefaultConstructible>
{
@@ -166,7 +163,7 @@ class sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>
{
public:
explicit sax_no_exception(json& j)
: nlohmann::detail::json_sax_dom_parser<json>(j, false)
: 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)
@@ -191,9 +188,11 @@ class my_allocator : public std::allocator<T>
using std::allocator<T>::allocator;
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
{
using other = my_allocator<U>;
@@ -230,7 +229,7 @@ inline void from_json(const nlohmann::json& j, FooBar& fb)
// for #3171
/////////////////////////////////////////////////////////////////////
struct for_3171_base // NOLINT(cppcoreguidelines-special-member-functions)
struct for_3171_base // NOLINT(cppcoreguidelines-special-member-functions)
{
for_3171_base(const std::string& /*unused*/ = {}) {}
virtual ~for_3171_base() = default;
@@ -246,7 +245,7 @@ struct for_3171_base // NOLINT(cppcoreguidelines-special-member-functions)
struct for_3171_derived : public for_3171_base
{
for_3171_derived() = default;
explicit for_3171_derived(const std::string& /*unused*/) { }
explicit for_3171_derived(const std::string& /*unused*/) {}
};
inline void from_json(const json& j, for_3171_base& tb)
@@ -277,7 +276,7 @@ inline void from_json(const json& j, for_3312& obj)
struct for_3204_foo
{
for_3204_foo() = default;
explicit for_3204_foo(std::string /*unused*/) {} // NOLINT(performance-unnecessary-value-param)
explicit for_3204_foo(std::string /*unused*/) {} // NOLINT(performance-unnecessary-value-param)
};
struct for_3204_bar
@@ -289,10 +288,12 @@ struct for_3204_bar
constructed_from_json = 2
};
explicit for_3204_bar(std::function<void(for_3204_foo)> /*unused*/) noexcept // NOLINT(performance-unnecessary-value-param)
: constructed_from(constructed_from_foo) {}
explicit for_3204_bar(std::function<void(json)> /*unused*/) noexcept // NOLINT(performance-unnecessary-value-param)
: constructed_from(constructed_from_json) {}
explicit for_3204_bar(std::function<void(for_3204_foo)> /*unused*/) noexcept // NOLINT(performance-unnecessary-value-param)
: constructed_from(constructed_from_foo)
{}
explicit for_3204_bar(std::function<void(json)> /*unused*/) noexcept // NOLINT(performance-unnecessary-value-param)
: constructed_from(constructed_from_json)
{}
constructed_from_t constructed_from = constructed_from_none;
};
@@ -303,9 +304,12 @@ struct for_3204_bar
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*/)
{
CHECK(false);
@@ -315,9 +319,9 @@ struct for_3333 final
int y = 0;
};
template <>
template<>
inline for_3333::for_3333(const json& j)
: for_3333(j.value("x", 0), j.value("y", 0))
: for_3333(j.value("x", 0), j.value("y", 0))
{}
TEST_CASE("regression tests 2")
@@ -359,8 +363,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
if (event == json::parse_event_t::value && !parsed.is_primitive())
{
@@ -432,11 +435,10 @@ TEST_CASE("regression tests 2")
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
return comper_pair(e1.key(), e1.value()) < comper_pair(e2.key(), e2.value()); // Using pair comper
});
[&](const it_type& e1, const it_type& e2) -> bool {
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
});
CHECK(diffs.size() == 1); // Note the change here, was 2
}
@@ -452,14 +454,13 @@ TEST_CASE("regression tests 2")
"with std::pair")
{
const json j =
{
{"1", {{"a", "testa_1"}, {"b", "testb_1"}}},
{"2", {{"a", "testa_2"}, {"b", "testb_2"}}},
{"3", {{"a", "testa_3"}, {"b", "testb_3"}}},
};
{
{"1", {{"a", "testa_1"}, {"b", "testb_1"}}},
{"2", {{"a", "testa_2"}, {"b", "testb_2"}}},
{"3", {{"a", "testa_3"}, {"b", "testb_3"}}},
};
std::map<std::string, Data> expected
{
std::map<std::string, Data> expected{
{"1", {"testa_1", "testb_1"}},
{"2", {"testa_2", "testb_2"}},
{"3", {"testa_3", "testb_3"}},
@@ -508,9 +509,8 @@ TEST_CASE("regression tests 2")
{
nlohmann::json dump_test;
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, 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}
};
{
{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}};
std::string s;
for (const int i : data)
{
@@ -614,7 +614,7 @@ TEST_CASE("regression tests 2")
' ', // Indent char
false, // Ensure ascii
json::error_handler_t::strict // Error
));
));
}
SECTION("PR #2181 - regression bug with lvalue")
@@ -629,18 +629,17 @@ TEST_CASE("regression tests 2")
SECTION("issue #2293 - eof doesn't cause parsing to stop")
{
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);
CHECK(result.is_discarded());
}
@@ -656,8 +655,7 @@ TEST_CASE("regression tests 2")
CHECK(jsonAnimals == jsonAnimals_parsed);
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;
for (const auto& data : intData)
{
@@ -675,15 +673,15 @@ TEST_CASE("regression tests 2")
}
#ifdef JSON_HAS_CPP_20
#if __has_include(<span>)
#if __has_include(<span>)
SECTION("issue #2546 - parsing containers of std::byte")
{
const char DATA[] = R"("Hello, world!")"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const char DATA[] = R"("Hello, world!")"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const auto s = std::as_bytes(std::span(DATA));
const json j = json::parse(s);
CHECK(j.dump() == "\"Hello, world!\"");
}
#endif
#endif
#endif
SECTION("issue #2574 - Deserialization to std::array, std::pair, and std::tuple with non-default constructable types fails")
@@ -834,10 +832,10 @@ TEST_CASE("regression tests 2")
const auto j_path = j.get<nlohmann::detail::std_fs::path>();
CHECK(j_path == text_path);
#if DOCTEST_CLANG || DOCTEST_GCC >= DOCTEST_COMPILER(8, 4, 0)
#if DOCTEST_CLANG || DOCTEST_GCC >= DOCTEST_COMPILER(8, 4, 0)
// only known to work on Clang and GCC >=8.4
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
#endif
}
#endif
@@ -858,17 +856,17 @@ TEST_CASE("regression tests 2")
CHECK(j.dump() == "[1,2,4]");
j.erase(std::remove_if(j.begin(), j.end(), [](const ordered_json & val)
{
return val == 2;
}), j.end());
j.erase(std::remove_if(j.begin(), j.end(), [](const ordered_json& val) {
return val == 2;
}),
j.end());
CHECK(j.dump() == "[1,4]");
}
SECTION("issue #3343 - json and ordered_json are not interchangable")
{
json::object_t jobj({ { "product", "one" } });
json::object_t jobj({{"product", "one"}});
ordered_json::object_t ojobj({{"product", "one"}});
auto jit = jobj.begin();
@@ -880,7 +878,7 @@ TEST_CASE("regression tests 2")
SECTION("issue #3171 - if class is_constructible from std::string wrong from_json overload is being selected, compilation failed")
{
const json j{{ "str", "value"}};
const json j{{"str", "value"}};
// failed with: error: no match for operator= (operand types are for_3171_derived and const nlohmann::basic_json<>::string_t
// {aka const std::__cxx11::basic_string<char>})
@@ -917,8 +915,8 @@ TEST_CASE("regression tests 2")
SECTION("issue #3204 - ambiguous regression")
{
for_3204_bar bar_from_foo([](for_3204_foo) noexcept {}); // NOLINT(performance-unnecessary-value-param)
for_3204_bar bar_from_json([](json) noexcept {}); // NOLINT(performance-unnecessary-value-param)
for_3204_bar bar_from_foo([](for_3204_foo) noexcept {}); // NOLINT(performance-unnecessary-value-param)
for_3204_bar bar_from_json([](json) noexcept {}); // NOLINT(performance-unnecessary-value-param)
CHECK(bar_from_foo.constructed_from == for_3204_bar::constructed_from_foo);
CHECK(bar_from_json.constructed_from == for_3204_bar::constructed_from_json);
@@ -926,11 +924,9 @@ TEST_CASE("regression tests 2")
SECTION("issue #3333 - Ambiguous conversion from nlohmann::basic_json<> to custom class")
{
const json j
{
const json j{
{"x", 1},
{"y", 2}
};
{"y", 2}};
for_3333 p = j;
CHECK(p.x == 1);
+132 -83
View File
@@ -11,8 +11,8 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#include <sstream>
#include <iomanip>
#include <sstream>
TEST_CASE("serialization")
{
@@ -118,41 +118,90 @@ TEST_CASE("serialization")
// https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf
// 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;
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"" + expected + "\"");
};
test("\xC2", "\\ufffd");
test("\xC2\x41\x42", "\\ufffd" "\x41" "\x42");
test("\xC2\xF4", "\\ufffd" "\\ufffd");
test("\xC2\x41\x42", "\\ufffd"
"\x41"
"\x42");
test("\xC2\xF4", "\\ufffd"
"\\ufffd");
test("\xF0\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\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("\xF1\x90\x80\x41", "\\ufffd" "\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("\xF0\x90\x80\x41", "\\ufffd"
"\x41");
test("\xF1\x90\x80\x41", "\\ufffd"
"\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("\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");
test("\xC0\xAF\xE0\x80\xBF\xF0\x81\x82\x41", "\\ufffd"
"\\ufffd"
"\\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")
{
auto test = [&](std::string const & input, std::string const & expected)
{
auto test = [&](std::string const& input, std::string const& expected) {
using std::to_string;
const json j = input;
CHECK(to_string(j) == "\"" + expected + "\"");
@@ -220,78 +269,78 @@ TEST_CASE("dump with binary values")
SECTION("pretty-printed")
{
CHECK(binary.dump(4) == "{\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": null\n"
"}");
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": null\n"
"}");
CHECK(binary_empty.dump(4) == "{\n"
" \"bytes\": [],\n"
" \"subtype\": null\n"
"}");
" \"bytes\": [],\n"
" \"subtype\": null\n"
"}");
CHECK(binary_with_subtype.dump(4) == "{\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": 128\n"
"}");
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": 128\n"
"}");
CHECK(binary_empty_with_subtype.dump(4) == "{\n"
" \"bytes\": [],\n"
" \"subtype\": 128\n"
"}");
" \"bytes\": [],\n"
" \"subtype\": 128\n"
"}");
CHECK(object.dump(4) == "{\n"
" \"key\": {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": null\n"
" }\n"
"}");
" \"key\": {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": null\n"
" }\n"
"}");
CHECK(object_empty.dump(4) == "{\n"
" \"key\": {\n"
" \"bytes\": [],\n"
" \"subtype\": null\n"
" }\n"
"}");
" \"key\": {\n"
" \"bytes\": [],\n"
" \"subtype\": null\n"
" }\n"
"}");
CHECK(object_with_subtype.dump(4) == "{\n"
" \"key\": {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": 128\n"
" }\n"
"}");
" \"key\": {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": 128\n"
" }\n"
"}");
CHECK(object_empty_with_subtype.dump(4) == "{\n"
" \"key\": {\n"
" \"bytes\": [],\n"
" \"subtype\": 128\n"
" }\n"
"}");
" \"key\": {\n"
" \"bytes\": [],\n"
" \"subtype\": 128\n"
" }\n"
"}");
CHECK(array.dump(4) == "[\n"
" \"value\",\n"
" 1,\n"
" {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": null\n"
" }\n"
"]");
" \"value\",\n"
" 1,\n"
" {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": null\n"
" }\n"
"]");
CHECK(array_empty.dump(4) == "[\n"
" \"value\",\n"
" 1,\n"
" {\n"
" \"bytes\": [],\n"
" \"subtype\": null\n"
" }\n"
"]");
" \"value\",\n"
" 1,\n"
" {\n"
" \"bytes\": [],\n"
" \"subtype\": null\n"
" }\n"
"]");
CHECK(array_with_subtype.dump(4) == "[\n"
" \"value\",\n"
" 1,\n"
" {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": 128\n"
" }\n"
"]");
" \"value\",\n"
" 1,\n"
" {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": 128\n"
" }\n"
"]");
CHECK(array_empty_with_subtype.dump(4) == "[\n"
" \"value\",\n"
" 1,\n"
" {\n"
" \"bytes\": [],\n"
" \"subtype\": 128\n"
" }\n"
"]");
" \"value\",\n"
" 1,\n"
" {\n"
" \"bytes\": [],\n"
" \"subtype\": 128\n"
" }\n"
"]");
}
}
File diff suppressed because it is too large Load Diff
+263 -269
View File
@@ -15,8 +15,7 @@
#include <nlohmann/json.hpp>
using nlohmann::detail::dtoa_impl::reinterpret_bits;
namespace
{
namespace {
float make_float(uint32_t sign_bit, uint32_t biased_exponent, uint32_t significand)
{
assert(sign_bit == 0 || sign_bit == 1);
@@ -35,12 +34,12 @@ float make_float(uint32_t sign_bit, uint32_t biased_exponent, uint32_t significa
// ldexp -- convert f * 2^e to IEEE single precision
float make_float(uint64_t f, int e)
{
constexpr uint64_t kHiddenBit = 0x00800000;
constexpr uint64_t kSignificandMask = 0x007FFFFF;
constexpr int kPhysicalSignificandSize = 23; // Excludes the hidden bit.
constexpr int kExponentBias = 0x7F + kPhysicalSignificandSize;
constexpr int kDenormalExponent = 1 - kExponentBias;
constexpr int kMaxExponent = 0xFF - kExponentBias;
constexpr uint64_t kHiddenBit = 0x00800000;
constexpr uint64_t kSignificandMask = 0x007FFFFF;
constexpr int kPhysicalSignificandSize = 23; // Excludes the hidden bit.
constexpr int kExponentBias = 0x7F + kPhysicalSignificandSize;
constexpr int kDenormalExponent = 1 - kExponentBias;
constexpr int kMaxExponent = 0xFF - kExponentBias;
while (f > kHiddenBit + kSignificandMask)
{
@@ -62,8 +61,8 @@ float make_float(uint64_t f, int e)
}
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);
return reinterpret_bits<float>(static_cast<uint32_t>(bits));
@@ -87,12 +86,12 @@ double make_double(uint64_t sign_bit, uint64_t biased_exponent, uint64_t signifi
// ldexp -- convert f * 2^e to IEEE double precision
double make_double(uint64_t f, int e)
{
constexpr uint64_t kHiddenBit = 0x0010000000000000;
constexpr uint64_t kSignificandMask = 0x000FFFFFFFFFFFFF;
constexpr int kPhysicalSignificandSize = 52; // Excludes the hidden bit.
constexpr int kExponentBias = 0x3FF + kPhysicalSignificandSize;
constexpr int kDenormalExponent = 1 - kExponentBias;
constexpr int kMaxExponent = 0x7FF - kExponentBias;
constexpr uint64_t kHiddenBit = 0x0010000000000000;
constexpr uint64_t kSignificandMask = 0x000FFFFFFFFFFFFF;
constexpr int kPhysicalSignificandSize = 52; // Excludes the hidden bit.
constexpr int kExponentBias = 0x3FF + kPhysicalSignificandSize;
constexpr int kDenormalExponent = 1 - kExponentBias;
constexpr int kMaxExponent = 0x7FF - kExponentBias;
while (f > kHiddenBit + kSignificandMask)
{
@@ -114,20 +113,19 @@ double make_double(uint64_t f, int e)
}
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);
return reinterpret_bits<double>(bits);
}
} // namespace
} // namespace
TEST_CASE("digit gen")
{
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(digits)
CAPTURE(expected_exponent)
@@ -141,57 +139,56 @@ TEST_CASE("digit gen")
CHECK(expected_exponent == exponent);
};
check_float(make_float(0, 0, 0x00000001), "1", -45); // min denormal
check_float(make_float(0, 0, 0x007FFFFF), "11754942", -45); // max denormal
check_float(make_float(0, 1, 0x00000000), "11754944", -45); // min normal
check_float(make_float(0, 1, 0x00000001), "11754945", -45);
check_float(make_float(0, 1, 0x007FFFFF), "23509886", -45);
check_float(make_float(0, 2, 0x00000000), "23509887", -45);
check_float(make_float(0, 2, 0x00000001), "2350989", -44);
check_float(make_float(0, 24, 0x00000000), "98607613", -39); // fail if no special case in normalized boundaries
check_float(make_float(0, 30, 0x00000000), "63108872", -37); // fail if no special case in normalized boundaries
check_float(make_float(0, 31, 0x00000000), "12621775", -36); // fail if no special case in normalized boundaries
check_float(make_float(0, 57, 0x00000000), "84703295", -29); // fail if no special case in normalized boundaries
check_float(make_float(0, 254, 0x007FFFFE), "34028233", 31);
check_float(make_float(0, 254, 0x007FFFFF), "34028235", 31); // max normal
check_float(make_float(0, 0, 0x00000001), "1", -45); // min denormal
check_float(make_float(0, 0, 0x007FFFFF), "11754942", -45); // max denormal
check_float(make_float(0, 1, 0x00000000), "11754944", -45); // min normal
check_float(make_float(0, 1, 0x00000001), "11754945", -45);
check_float(make_float(0, 1, 0x007FFFFF), "23509886", -45);
check_float(make_float(0, 2, 0x00000000), "23509887", -45);
check_float(make_float(0, 2, 0x00000001), "2350989", -44);
check_float(make_float(0, 24, 0x00000000), "98607613", -39); // fail if no special case in normalized boundaries
check_float(make_float(0, 30, 0x00000000), "63108872", -37); // fail if no special case in normalized boundaries
check_float(make_float(0, 31, 0x00000000), "12621775", -36); // fail if no special case in normalized boundaries
check_float(make_float(0, 57, 0x00000000), "84703295", -29); // fail if no special case in normalized boundaries
check_float(make_float(0, 254, 0x007FFFFE), "34028233", 31);
check_float(make_float(0, 254, 0x007FFFFF), "34028235", 31); // max normal
// V. Paxson and W. Kahan, "A Program for Testing IEEE Binary-Decimal Conversion", manuscript, May 1991,
// ftp://ftp.ee.lbl.gov/testbase-report.ps.Z (report)
// ftp://ftp.ee.lbl.gov/testbase.tar.Z (program)
// Table 16: Stress Inputs for Converting 24-bit Binary to Decimal, < 1/2 ULP
check_float(make_float(12676506, -102), "25", -25);
check_float(make_float(12676506, -103), "125", -26);
check_float(make_float(15445013, 86), "1195", 30);
check_float(make_float(13734123, -138), "39415", -39);
check_float(make_float(12428269, -130), "913085", -38);
check_float(make_float(15334037, -146), "1719005", -43);
check_float(make_float(11518287, -41), "52379105", -13);
check_float(make_float(12584953, -145), "2821644", -43);
check_float(make_float(12676506, -102), "25", -25);
check_float(make_float(12676506, -103), "125", -26);
check_float(make_float(15445013, 86), "1195", 30);
check_float(make_float(13734123, -138), "39415", -39);
check_float(make_float(12428269, -130), "913085", -38);
check_float(make_float(15334037, -146), "1719005", -43);
check_float(make_float(11518287, -41), "52379105", -13);
check_float(make_float(12584953, -145), "2821644", -43);
check_float(make_float(15961084, -125), "37524328", -38);
check_float(make_float(14915817, -146), "16721209", -44);
check_float(make_float(10845484, -102), "21388946", -31);
check_float(make_float(16431059, -61), "7125836", -18);
check_float(make_float(16431059, -61), "7125836", -18);
// Table 17: Stress Inputs for Converting 24-bit Binary to Decimal, > 1/2 ULP
check_float(make_float(16093626, 69), "95", 26);
check_float(make_float( 9983778, 25), "335", 12);
check_float(make_float(12745034, 104), "2585", 35);
check_float(make_float(12706553, 72), "60005", 24);
check_float(make_float(11005028, 45), "387205", 15);
check_float(make_float(15059547, 71), "3555835", 22);
check_float(make_float(16015691, -99), "25268305", -30);
check_float(make_float( 8667859, 56), "6245851", 17);
check_float(make_float(14855922, -82), "30721327", -25);
check_float(make_float(14855922, -83), "15360663", -25);
check_float(make_float(10144164, -110), "781478", -32);
check_float(make_float(13248074, 95), "52481028", 28);
check_float(make_float(16093626, 69), "95", 26);
check_float(make_float(9983778, 25), "335", 12);
check_float(make_float(12745034, 104), "2585", 35);
check_float(make_float(12706553, 72), "60005", 24);
check_float(make_float(11005028, 45), "387205", 15);
check_float(make_float(15059547, 71), "3555835", 22);
check_float(make_float(16015691, -99), "25268305", -30);
check_float(make_float(8667859, 56), "6245851", 17);
check_float(make_float(14855922, -82), "30721327", -25);
check_float(make_float(14855922, -83), "15360663", -25);
check_float(make_float(10144164, -110), "781478", -32);
check_float(make_float(13248074, 95), "52481028", 28);
}
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(digits)
CAPTURE(expected_exponent)
@@ -205,130 +202,130 @@ TEST_CASE("digit gen")
CHECK(expected_exponent == exponent);
};
check_double(make_double(0, 0, 0x0000000000000001), "5", -324); // min denormal
check_double(make_double(0, 0, 0x000FFFFFFFFFFFFF), "2225073858507201", -323); // max denormal
check_double(make_double(0, 1, 0x0000000000000000), "22250738585072014", -324); // min normal
check_double(make_double(0, 1, 0x0000000000000001), "2225073858507202", -323);
check_double(make_double(0, 1, 0x000FFFFFFFFFFFFF), "44501477170144023", -324);
check_double(make_double(0, 2, 0x0000000000000000), "4450147717014403", -323);
check_double(make_double(0, 2, 0x0000000000000001), "4450147717014404", -323);
check_double(make_double(0, 4, 0x0000000000000000), "17800590868057611", -323); // fail if no special case in normalized boundaries
check_double(make_double(0, 5, 0x0000000000000000), "35601181736115222", -323); // fail if no special case in normalized boundaries
check_double(make_double(0, 6, 0x0000000000000000), "7120236347223045", -322); // fail if no special case in normalized boundaries
check_double(make_double(0, 10, 0x0000000000000000), "11392378155556871", -321); // fail if no special case in normalized boundaries
check_double(make_double(0, 2046, 0x000FFFFFFFFFFFFE), "17976931348623155", 292);
check_double(make_double(0, 2046, 0x000FFFFFFFFFFFFF), "17976931348623157", 292); // max normal
check_double(make_double(0, 0, 0x0000000000000001), "5", -324); // min denormal
check_double(make_double(0, 0, 0x000FFFFFFFFFFFFF), "2225073858507201", -323); // max denormal
check_double(make_double(0, 1, 0x0000000000000000), "22250738585072014", -324); // min normal
check_double(make_double(0, 1, 0x0000000000000001), "2225073858507202", -323);
check_double(make_double(0, 1, 0x000FFFFFFFFFFFFF), "44501477170144023", -324);
check_double(make_double(0, 2, 0x0000000000000000), "4450147717014403", -323);
check_double(make_double(0, 2, 0x0000000000000001), "4450147717014404", -323);
check_double(make_double(0, 4, 0x0000000000000000), "17800590868057611", -323); // fail if no special case in normalized boundaries
check_double(make_double(0, 5, 0x0000000000000000), "35601181736115222", -323); // fail if no special case in normalized boundaries
check_double(make_double(0, 6, 0x0000000000000000), "7120236347223045", -322); // fail if no special case in normalized boundaries
check_double(make_double(0, 10, 0x0000000000000000), "11392378155556871", -321); // fail if no special case in normalized boundaries
check_double(make_double(0, 2046, 0x000FFFFFFFFFFFFE), "17976931348623155", 292);
check_double(make_double(0, 2046, 0x000FFFFFFFFFFFFF), "17976931348623157", 292); // max normal
// Test different paths in DigitGen
check_double( 10000, "1", 4);
check_double( 1200000, "12", 5);
check_double(4.9406564584124654e-324, "5", -324); // exit integral loop
check_double(2.2250738585072009e-308, "2225073858507201", -323); // exit fractional loop
check_double( 1.82877982605164e-99, "182877982605164", -113);
check_double( 1.1505466208671903e-09, "11505466208671903", -25);
check_double( 5.5645893133766722e+20, "5564589313376672", 5);
check_double( 53.034830388866226, "53034830388866226", -15);
check_double( 0.0021066531670178605, "21066531670178605", -19);
check_double(10000, "1", 4);
check_double(1200000, "12", 5);
check_double(4.9406564584124654e-324, "5", -324); // exit integral loop
check_double(2.2250738585072009e-308, "2225073858507201", -323); // exit fractional loop
check_double(1.82877982605164e-99, "182877982605164", -113);
check_double(1.1505466208671903e-09, "11505466208671903", -25);
check_double(5.5645893133766722e+20, "5564589313376672", 5);
check_double(53.034830388866226, "53034830388866226", -15);
check_double(0.0021066531670178605, "21066531670178605", -19);
// V. Paxson and W. Kahan, "A Program for Testing IEEE Binary-Decimal Conversion", manuscript, May 1991,
// ftp://ftp.ee.lbl.gov/testbase-report.ps.Z (report)
// ftp://ftp.ee.lbl.gov/testbase.tar.Z (program)
// Table 3: Stress Inputs for Converting 53-bit Binary to Decimal, < 1/2 ULP
check_double(make_double(8511030020275656, -342) /* 9.5e-088 */, "95", -89);
check_double(make_double(5201988407066741, -824) /* 4.65e-233 */, "465", -235);
check_double(make_double(6406892948269899, +237) /* 1.415e+087 */, "1415", 84);
check_double(make_double(8431154198732492, +72) /* 3.9815e+037 */, "39815", 33);
check_double(make_double(6475049196144587, +99) /* 4.10405e+045 */, "410405", 40);
check_double(make_double(8274307542972842, +726) /* 2.920845e+234 */, "2920845", 228);
check_double(make_double(5381065484265332, -456) /* 2.8919465e-122 */, "28919465", -129);
check_double(make_double(6761728585499734, -1057) /* 4.37877185e-303 */, "437877185", -311);
check_double(make_double(7976538478610756, +376) /* 1.227701635e+129 */, "1227701635", 120);
check_double(make_double(5982403858958067, +377) /* 1.8415524525e+129 */, "18415524525", 119);
check_double(make_double(5536995190630837, +93) /* 5.48357443505e+043 */, "548357443505", 32);
check_double(make_double(7225450889282194, +710) /* 3.891901811465e+229 */, "3891901811465", 217);
check_double(make_double(7225450889282194, +709) /* 1.9459509057325e+229 */, "19459509057325", 216);
check_double(make_double(8703372741147379, +117) /* 1.44609583816055e+051 */, "144609583816055", 37);
check_double(make_double(8944262675275217, -1001) /* 4.173677474585315e-286 */, "4173677474585315", -301);
check_double(make_double(7459803696087692, -707) /* 1.1079507728788885e-197 */, "11079507728788885", -213);
check_double(make_double(6080469016670379, -381) /* 1.234550136632744e-099 */, "1234550136632744", -114);
check_double(make_double(8385515147034757, +721) /* 9.2503171196036502e+232 */, "925031711960365", 218);
check_double(make_double(7514216811389786, -828) /* 4.1980471502848898e-234 */, "419804715028489", -248);
check_double(make_double(8397297803260511, -345) /* 1.1716315319786511e-088 */, "11716315319786511", -104);
check_double(make_double(6733459239310543, +202) /* 4.3281007284461249e+076 */, "4328100728446125", 61);
check_double(make_double(8091450587292794, -473) /* 3.3177101181600311e-127 */, "3317710118160031", -142);
check_double(make_double(8511030020275656, -342) /* 9.5e-088 */, "95", -89);
check_double(make_double(5201988407066741, -824) /* 4.65e-233 */, "465", -235);
check_double(make_double(6406892948269899, +237) /* 1.415e+087 */, "1415", 84);
check_double(make_double(8431154198732492, +72) /* 3.9815e+037 */, "39815", 33);
check_double(make_double(6475049196144587, +99) /* 4.10405e+045 */, "410405", 40);
check_double(make_double(8274307542972842, +726) /* 2.920845e+234 */, "2920845", 228);
check_double(make_double(5381065484265332, -456) /* 2.8919465e-122 */, "28919465", -129);
check_double(make_double(6761728585499734, -1057) /* 4.37877185e-303 */, "437877185", -311);
check_double(make_double(7976538478610756, +376) /* 1.227701635e+129 */, "1227701635", 120);
check_double(make_double(5982403858958067, +377) /* 1.8415524525e+129 */, "18415524525", 119);
check_double(make_double(5536995190630837, +93) /* 5.48357443505e+043 */, "548357443505", 32);
check_double(make_double(7225450889282194, +710) /* 3.891901811465e+229 */, "3891901811465", 217);
check_double(make_double(7225450889282194, +709) /* 1.9459509057325e+229 */, "19459509057325", 216);
check_double(make_double(8703372741147379, +117) /* 1.44609583816055e+051 */, "144609583816055", 37);
check_double(make_double(8944262675275217, -1001) /* 4.173677474585315e-286 */, "4173677474585315", -301);
check_double(make_double(7459803696087692, -707) /* 1.1079507728788885e-197 */, "11079507728788885", -213);
check_double(make_double(6080469016670379, -381) /* 1.234550136632744e-099 */, "1234550136632744", -114);
check_double(make_double(8385515147034757, +721) /* 9.2503171196036502e+232 */, "925031711960365", 218);
check_double(make_double(7514216811389786, -828) /* 4.1980471502848898e-234 */, "419804715028489", -248);
check_double(make_double(8397297803260511, -345) /* 1.1716315319786511e-088 */, "11716315319786511", -104);
check_double(make_double(6733459239310543, +202) /* 4.3281007284461249e+076 */, "4328100728446125", 61);
check_double(make_double(8091450587292794, -473) /* 3.3177101181600311e-127 */, "3317710118160031", -142);
// Table 4: Stress Inputs for Converting 53-bit Binary to Decimal, > 1/2 ULP
check_double(make_double(6567258882077402, +952) /* 2.5e+302 */, "25", 301);
check_double(make_double(6712731423444934, +535) /* 7.55e+176 */, "755", 174);
check_double(make_double(6712731423444934, +534) /* 3.775e+176 */, "3775", 173);
check_double(make_double(5298405411573037, -957) /* 4.3495e-273 */, "43495", -277);
check_double(make_double(5137311167659507, -144) /* 2.30365e-028 */, "230365", -33);
check_double(make_double(6722280709661868, +363) /* 1.263005e+125 */, "1263005", 119);
check_double(make_double(5344436398034927, -169) /* 7.1422105e-036 */, "71422105", -43);
check_double(make_double(8369123604277281, -853) /* 1.39345735e-241 */, "139345735", -249);
check_double(make_double(8995822108487663, -780) /* 1.414634485e-219 */, "1414634485", -228);
check_double(make_double(8942832835564782, -383) /* 4.5392779195e-100 */, "45392779195", -110);
check_double(make_double(8942832835564782, -384) /* 2.26963895975e-100 */, "226963895975", -111);
check_double(make_double(8942832835564782, -385) /* 1.134819479875e-100 */, "1134819479875", -112);
check_double(make_double(6965949469487146, -249) /* 7.7003665618895e-060 */, "77003665618895", -73);
check_double(make_double(6965949469487146, -250) /* 3.85018328094475e-060 */, "385018328094475", -74);
check_double(make_double(6965949469487146, -251) /* 1.925091640472375e-060 */, "1925091640472375", -75);
check_double(make_double(7487252720986826, +548) /* 6.8985865317742005e+180 */, "68985865317742005", 164);
check_double(make_double(5592117679628511, +164) /* 1.3076622631878654e+065 */, "13076622631878654", 49);
check_double(make_double(8887055249355788, +665) /* 1.3605202075612124e+216 */, "13605202075612124", 200);
check_double(make_double(6994187472632449, +690) /* 3.5928102174759597e+223 */, "35928102174759597", 207);
check_double(make_double(8797576579012143, +588) /* 8.9125197712484552e+192 */, "8912519771248455", 177);
check_double(make_double(7363326733505337, +272) /* 5.5876975736230114e+097 */, "55876975736230114", 81);
check_double(make_double(8549497411294502, -448) /* 1.1762578307285404e-119 */, "11762578307285404", -135);
check_double(make_double(6567258882077402, +952) /* 2.5e+302 */, "25", 301);
check_double(make_double(6712731423444934, +535) /* 7.55e+176 */, "755", 174);
check_double(make_double(6712731423444934, +534) /* 3.775e+176 */, "3775", 173);
check_double(make_double(5298405411573037, -957) /* 4.3495e-273 */, "43495", -277);
check_double(make_double(5137311167659507, -144) /* 2.30365e-028 */, "230365", -33);
check_double(make_double(6722280709661868, +363) /* 1.263005e+125 */, "1263005", 119);
check_double(make_double(5344436398034927, -169) /* 7.1422105e-036 */, "71422105", -43);
check_double(make_double(8369123604277281, -853) /* 1.39345735e-241 */, "139345735", -249);
check_double(make_double(8995822108487663, -780) /* 1.414634485e-219 */, "1414634485", -228);
check_double(make_double(8942832835564782, -383) /* 4.5392779195e-100 */, "45392779195", -110);
check_double(make_double(8942832835564782, -384) /* 2.26963895975e-100 */, "226963895975", -111);
check_double(make_double(8942832835564782, -385) /* 1.134819479875e-100 */, "1134819479875", -112);
check_double(make_double(6965949469487146, -249) /* 7.7003665618895e-060 */, "77003665618895", -73);
check_double(make_double(6965949469487146, -250) /* 3.85018328094475e-060 */, "385018328094475", -74);
check_double(make_double(6965949469487146, -251) /* 1.925091640472375e-060 */, "1925091640472375", -75);
check_double(make_double(7487252720986826, +548) /* 6.8985865317742005e+180 */, "68985865317742005", 164);
check_double(make_double(5592117679628511, +164) /* 1.3076622631878654e+065 */, "13076622631878654", 49);
check_double(make_double(8887055249355788, +665) /* 1.3605202075612124e+216 */, "13605202075612124", 200);
check_double(make_double(6994187472632449, +690) /* 3.5928102174759597e+223 */, "35928102174759597", 207);
check_double(make_double(8797576579012143, +588) /* 8.9125197712484552e+192 */, "8912519771248455", 177);
check_double(make_double(7363326733505337, +272) /* 5.5876975736230114e+097 */, "55876975736230114", 81);
check_double(make_double(8549497411294502, -448) /* 1.1762578307285404e-119 */, "11762578307285404", -135);
// Table 20: Stress Inputs for Converting 56-bit Binary to Decimal, < 1/2 ULP
check_double(make_double(50883641005312716, -172) /* 8.4999999999999993e-036 */, "8499999999999999", -51);
check_double(make_double(38162730753984537, -170) /* 2.5499999999999999e-035 */, "255", -37);
check_double(make_double(50832789069151999, -101) /* 2.0049999999999997e-014 */, "20049999999999997", -30);
check_double(make_double(51822367833714164, -109) /* 7.9844999999999994e-017 */, "7984499999999999", -32);
check_double(make_double(66840152193508133, -172) /* 1.1165499999999999e-035 */, "11165499999999999", -51);
check_double(make_double(55111239245584393, -138) /* 1.581615e-025 */, "1581615", -31);
check_double(make_double(71704866733321482, -112) /* 1.3809855e-017 */, "13809855", -24);
check_double(make_double(67160949328233173, -142) /* 1.2046404499999999e-026 */, "12046404499999999", -42);
check_double(make_double(53237141308040189, -152) /* 9.3251405449999991e-030 */, "9325140544999999", -45);
check_double(make_double(62785329394975786, -112) /* 1.2092014595e-017 */, "12092014595", -27);
check_double(make_double(48367680154689523, -77) /* 3.2007045838499998e-007 */, "320070458385", -18);
check_double(make_double(42552223180606797, -102) /* 8.391946324354999e-015 */, "8391946324354999", -30);
check_double(make_double(63626356173011241, -112) /* 1.2253990460585e-017 */, "12253990460585", -30);
check_double(make_double(43566388595783643, -99) /* 6.8735641489760495e-014 */, "687356414897605", -28);
check_double(make_double(54512669636675272, -159) /* 7.459816430480385e-032 */, "7459816430480385", -47);
check_double(make_double(52306490527514614, -167) /* 2.7960588398142552e-034 */, "2796058839814255", -49);
check_double(make_double(52306490527514614, -168) /* 1.3980294199071276e-034 */, "13980294199071276", -50);
check_double(make_double(41024721590449423, -89) /* 6.6279012373057359e-011 */, "6627901237305736", -26);
check_double(make_double(37664020415894738, -132) /* 6.9177880043968072e-024 */, "6917788004396807", -39);
check_double(make_double(37549883692866294, -93) /* 3.7915693108349708e-012 */, "3791569310834971", -27);
check_double(make_double(69124110374399839, -104) /* 3.4080817676591365e-015 */, "34080817676591365", -31);
check_double(make_double(69124110374399839, -105) /* 1.7040408838295683e-015 */, "17040408838295683", -31);
check_double(make_double(50883641005312716, -172) /* 8.4999999999999993e-036 */, "8499999999999999", -51);
check_double(make_double(38162730753984537, -170) /* 2.5499999999999999e-035 */, "255", -37);
check_double(make_double(50832789069151999, -101) /* 2.0049999999999997e-014 */, "20049999999999997", -30);
check_double(make_double(51822367833714164, -109) /* 7.9844999999999994e-017 */, "7984499999999999", -32);
check_double(make_double(66840152193508133, -172) /* 1.1165499999999999e-035 */, "11165499999999999", -51);
check_double(make_double(55111239245584393, -138) /* 1.581615e-025 */, "1581615", -31);
check_double(make_double(71704866733321482, -112) /* 1.3809855e-017 */, "13809855", -24);
check_double(make_double(67160949328233173, -142) /* 1.2046404499999999e-026 */, "12046404499999999", -42);
check_double(make_double(53237141308040189, -152) /* 9.3251405449999991e-030 */, "9325140544999999", -45);
check_double(make_double(62785329394975786, -112) /* 1.2092014595e-017 */, "12092014595", -27);
check_double(make_double(48367680154689523, -77) /* 3.2007045838499998e-007 */, "320070458385", -18);
check_double(make_double(42552223180606797, -102) /* 8.391946324354999e-015 */, "8391946324354999", -30);
check_double(make_double(63626356173011241, -112) /* 1.2253990460585e-017 */, "12253990460585", -30);
check_double(make_double(43566388595783643, -99) /* 6.8735641489760495e-014 */, "687356414897605", -28);
check_double(make_double(54512669636675272, -159) /* 7.459816430480385e-032 */, "7459816430480385", -47);
check_double(make_double(52306490527514614, -167) /* 2.7960588398142552e-034 */, "2796058839814255", -49);
check_double(make_double(52306490527514614, -168) /* 1.3980294199071276e-034 */, "13980294199071276", -50);
check_double(make_double(41024721590449423, -89) /* 6.6279012373057359e-011 */, "6627901237305736", -26);
check_double(make_double(37664020415894738, -132) /* 6.9177880043968072e-024 */, "6917788004396807", -39);
check_double(make_double(37549883692866294, -93) /* 3.7915693108349708e-012 */, "3791569310834971", -27);
check_double(make_double(69124110374399839, -104) /* 3.4080817676591365e-015 */, "34080817676591365", -31);
check_double(make_double(69124110374399839, -105) /* 1.7040408838295683e-015 */, "17040408838295683", -31);
// Table 21: Stress Inputs for Converting 56-bit Binary to Decimal, > 1/2 ULP
check_double(make_double(49517601571415211, -94) /* 2.4999999999999998e-012 */, "25", -13);
check_double(make_double(49517601571415211, -95) /* 1.2499999999999999e-012 */, "125", -14);
check_double(make_double(54390733528642804, -133) /* 4.9949999999999996e-024 */, "49949999999999996", -40); // shortest: 4995e-27
check_double(make_double(71805402319113924, -157) /* 3.9304999999999998e-031 */, "39304999999999998", -47); // shortest: 39305e-35
check_double(make_double(40435277969631694, -179) /* 5.2770499999999992e-038 */, "5277049999999999", -53);
check_double(make_double(57241991568619049, -165) /* 1.223955e-033 */, "1223955", -39);
check_double(make_double(65224162876242886, +58) /* 1.8799584999999998e+034 */, "18799584999999998", 18);
check_double(make_double(70173376848895368, -138) /* 2.01387715e-025 */, "201387715", -33);
check_double(make_double(37072848117383207, -99) /* 5.8490641049999989e-014 */, "5849064104999999", -29);
check_double(make_double(56845051585389697, -176) /* 5.9349003054999999e-037 */, "59349003055", -47);
check_double(make_double(54791673366936431, -145) /* 1.2284718039499998e-027 */, "12284718039499998", -43);
check_double(make_double(66800318669106231, -169) /* 8.9270767180849991e-035 */, "8927076718084999", -50);
check_double(make_double(66800318669106231, -170) /* 4.4635383590424995e-035 */, "44635383590424995", -51);
check_double(make_double(66574323440112438, -119) /* 1.0016990862549499e-019 */, "10016990862549499", -35);
check_double(make_double(65645179969330963, -173) /* 5.4829412628024647e-036 */, "5482941262802465", -51);
check_double(make_double(61847254334681076, -109) /* 9.5290783281036439e-017 */, "9529078328103644", -32);
check_double(make_double(39990712921393606, -145) /* 8.9662279366405553e-028 */, "8966227936640555", -43);
check_double(make_double(59292318184400283, -149) /* 8.3086234418058538e-029 */, "8308623441805854", -44);
check_double(make_double(69116558615326153, -143) /* 6.1985873566126555e-027 */, "61985873566126555", -43);
check_double(make_double(69116558615326153, -144) /* 3.0992936783063277e-027 */, "30992936783063277", -43);
check_double(make_double(39462549494468513, -152) /* 6.9123512506176015e-030 */, "6912351250617602", -45);
check_double(make_double(39462549494468513, -153) /* 3.4561756253088008e-030 */, "3456175625308801", -45);
check_double(make_double(49517601571415211, -94) /* 2.4999999999999998e-012 */, "25", -13);
check_double(make_double(49517601571415211, -95) /* 1.2499999999999999e-012 */, "125", -14);
check_double(make_double(54390733528642804, -133) /* 4.9949999999999996e-024 */, "49949999999999996", -40); // shortest: 4995e-27
check_double(make_double(71805402319113924, -157) /* 3.9304999999999998e-031 */, "39304999999999998", -47); // shortest: 39305e-35
check_double(make_double(40435277969631694, -179) /* 5.2770499999999992e-038 */, "5277049999999999", -53);
check_double(make_double(57241991568619049, -165) /* 1.223955e-033 */, "1223955", -39);
check_double(make_double(65224162876242886, +58) /* 1.8799584999999998e+034 */, "18799584999999998", 18);
check_double(make_double(70173376848895368, -138) /* 2.01387715e-025 */, "201387715", -33);
check_double(make_double(37072848117383207, -99) /* 5.8490641049999989e-014 */, "5849064104999999", -29);
check_double(make_double(56845051585389697, -176) /* 5.9349003054999999e-037 */, "59349003055", -47);
check_double(make_double(54791673366936431, -145) /* 1.2284718039499998e-027 */, "12284718039499998", -43);
check_double(make_double(66800318669106231, -169) /* 8.9270767180849991e-035 */, "8927076718084999", -50);
check_double(make_double(66800318669106231, -170) /* 4.4635383590424995e-035 */, "44635383590424995", -51);
check_double(make_double(66574323440112438, -119) /* 1.0016990862549499e-019 */, "10016990862549499", -35);
check_double(make_double(65645179969330963, -173) /* 5.4829412628024647e-036 */, "5482941262802465", -51);
check_double(make_double(61847254334681076, -109) /* 9.5290783281036439e-017 */, "9529078328103644", -32);
check_double(make_double(39990712921393606, -145) /* 8.9662279366405553e-028 */, "8966227936640555", -43);
check_double(make_double(59292318184400283, -149) /* 8.3086234418058538e-029 */, "8308623441805854", -44);
check_double(make_double(69116558615326153, -143) /* 6.1985873566126555e-027 */, "61985873566126555", -43);
check_double(make_double(69116558615326153, -144) /* 3.0992936783063277e-027 */, "30992936783063277", -43);
check_double(make_double(39462549494468513, -152) /* 6.9123512506176015e-030 */, "6912351250617602", -45);
check_double(make_double(39462549494468513, -153) /* 3.4561756253088008e-030 */, "3456175625308801", -45);
}
}
@@ -336,128 +333,125 @@ TEST_CASE("formatting")
{
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{};
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);
CHECK(actual == expected);
};
// %.9g
check_float( -1.2345e-22f, "-1.2345e-22" ); // -1.23450004e-22
check_float( -1.2345e-21f, "-1.2345e-21" ); // -1.23450002e-21
check_float( -1.2345e-20f, "-1.2345e-20" ); // -1.23450002e-20
check_float( -1.2345e-19f, "-1.2345e-19" ); // -1.23449999e-19
check_float( -1.2345e-18f, "-1.2345e-18" ); // -1.23449996e-18
check_float( -1.2345e-17f, "-1.2345e-17" ); // -1.23449998e-17
check_float( -1.2345e-16f, "-1.2345e-16" ); // -1.23449996e-16
check_float( -1.2345e-15f, "-1.2345e-15" ); // -1.23450002e-15
check_float( -1.2345e-14f, "-1.2345e-14" ); // -1.23450004e-14
check_float( -1.2345e-13f, "-1.2345e-13" ); // -1.23449997e-13
check_float( -1.2345e-12f, "-1.2345e-12" ); // -1.23450002e-12
check_float( -1.2345e-11f, "-1.2345e-11" ); // -1.2345e-11
check_float( -1.2345e-10f, "-1.2345e-10" ); // -1.2345e-10
check_float( -1.2345e-9f, "-1.2345e-09" ); // -1.23449995e-09
check_float( -1.2345e-8f, "-1.2345e-08" ); // -1.23449997e-08
check_float( -1.2345e-7f, "-1.2345e-07" ); // -1.23449993e-07
check_float( -1.2345e-6f, "-1.2345e-06" ); // -1.23450002e-06
check_float( -1.2345e-5f, "-1.2345e-05" ); // -1.2345e-05
check_float( -1.2345e-4f, "-0.00012345" ); // -0.000123449994
check_float( -1.2345e-3f, "-0.0012345" ); // -0.00123449997
check_float( -1.2345e-2f, "-0.012345" ); // -0.0123450002
check_float( -1.2345e-1f, "-0.12345" ); // -0.123450004
check_float( -0.0f, "-0.0" ); // -0
check_float( 0.0f, "0.0" ); // 0
check_float( 1.2345e+0f, "1.2345" ); // 1.23450005
check_float( 1.2345e+1f, "12.345" ); // 12.3450003
check_float( 1.2345e+2f, "123.45" ); // 123.449997
check_float( 1.2345e+3f, "1234.5" ); // 1234.5
check_float( 1.2345e+4f, "12345.0" ); // 12345
check_float( 1.2345e+5f, "123450.0" ); // 123450
check_float( 1.2345e+6f, "1.2345e+06" ); // 1234500
check_float( 1.2345e+7f, "1.2345e+07" ); // 12345000
check_float( 1.2345e+8f, "1.2345e+08" ); // 123450000
check_float( 1.2345e+9f, "1.2345e+09" ); // 1.23449997e+09
check_float( 1.2345e+10f, "1.2345e+10" ); // 1.23449999e+10
check_float( 1.2345e+11f, "1.2345e+11" ); // 1.23449999e+11
check_float( 1.2345e+12f, "1.2345e+12" ); // 1.23450006e+12
check_float( 1.2345e+13f, "1.2345e+13" ); // 1.23449995e+13
check_float( 1.2345e+14f, "1.2345e+14" ); // 1.23450002e+14
check_float( 1.2345e+15f, "1.2345e+15" ); // 1.23450003e+15
check_float( 1.2345e+16f, "1.2345e+16" ); // 1.23449998e+16
check_float( 1.2345e+17f, "1.2345e+17" ); // 1.23449996e+17
check_float( 1.2345e+18f, "1.2345e+18" ); // 1.23450004e+18
check_float( 1.2345e+19f, "1.2345e+19" ); // 1.23449999e+19
check_float( 1.2345e+20f, "1.2345e+20" ); // 1.23449999e+20
check_float( 1.2345e+21f, "1.2345e+21" ); // 1.23449999e+21
check_float( 1.2345e+22f, "1.2345e+22" ); // 1.23450005e+22
check_float(-1.2345e-22f, "-1.2345e-22"); // -1.23450004e-22
check_float(-1.2345e-21f, "-1.2345e-21"); // -1.23450002e-21
check_float(-1.2345e-20f, "-1.2345e-20"); // -1.23450002e-20
check_float(-1.2345e-19f, "-1.2345e-19"); // -1.23449999e-19
check_float(-1.2345e-18f, "-1.2345e-18"); // -1.23449996e-18
check_float(-1.2345e-17f, "-1.2345e-17"); // -1.23449998e-17
check_float(-1.2345e-16f, "-1.2345e-16"); // -1.23449996e-16
check_float(-1.2345e-15f, "-1.2345e-15"); // -1.23450002e-15
check_float(-1.2345e-14f, "-1.2345e-14"); // -1.23450004e-14
check_float(-1.2345e-13f, "-1.2345e-13"); // -1.23449997e-13
check_float(-1.2345e-12f, "-1.2345e-12"); // -1.23450002e-12
check_float(-1.2345e-11f, "-1.2345e-11"); // -1.2345e-11
check_float(-1.2345e-10f, "-1.2345e-10"); // -1.2345e-10
check_float(-1.2345e-9f, "-1.2345e-09"); // -1.23449995e-09
check_float(-1.2345e-8f, "-1.2345e-08"); // -1.23449997e-08
check_float(-1.2345e-7f, "-1.2345e-07"); // -1.23449993e-07
check_float(-1.2345e-6f, "-1.2345e-06"); // -1.23450002e-06
check_float(-1.2345e-5f, "-1.2345e-05"); // -1.2345e-05
check_float(-1.2345e-4f, "-0.00012345"); // -0.000123449994
check_float(-1.2345e-3f, "-0.0012345"); // -0.00123449997
check_float(-1.2345e-2f, "-0.012345"); // -0.0123450002
check_float(-1.2345e-1f, "-0.12345"); // -0.123450004
check_float(-0.0f, "-0.0"); // -0
check_float(0.0f, "0.0"); // 0
check_float(1.2345e+0f, "1.2345"); // 1.23450005
check_float(1.2345e+1f, "12.345"); // 12.3450003
check_float(1.2345e+2f, "123.45"); // 123.449997
check_float(1.2345e+3f, "1234.5"); // 1234.5
check_float(1.2345e+4f, "12345.0"); // 12345
check_float(1.2345e+5f, "123450.0"); // 123450
check_float(1.2345e+6f, "1.2345e+06"); // 1234500
check_float(1.2345e+7f, "1.2345e+07"); // 12345000
check_float(1.2345e+8f, "1.2345e+08"); // 123450000
check_float(1.2345e+9f, "1.2345e+09"); // 1.23449997e+09
check_float(1.2345e+10f, "1.2345e+10"); // 1.23449999e+10
check_float(1.2345e+11f, "1.2345e+11"); // 1.23449999e+11
check_float(1.2345e+12f, "1.2345e+12"); // 1.23450006e+12
check_float(1.2345e+13f, "1.2345e+13"); // 1.23449995e+13
check_float(1.2345e+14f, "1.2345e+14"); // 1.23450002e+14
check_float(1.2345e+15f, "1.2345e+15"); // 1.23450003e+15
check_float(1.2345e+16f, "1.2345e+16"); // 1.23449998e+16
check_float(1.2345e+17f, "1.2345e+17"); // 1.23449996e+17
check_float(1.2345e+18f, "1.2345e+18"); // 1.23450004e+18
check_float(1.2345e+19f, "1.2345e+19"); // 1.23449999e+19
check_float(1.2345e+20f, "1.2345e+20"); // 1.23449999e+20
check_float(1.2345e+21f, "1.2345e+21"); // 1.23449999e+21
check_float(1.2345e+22f, "1.2345e+22"); // 1.23450005e+22
}
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{};
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);
CHECK(actual == expected);
};
// dtoa %.15g %.17g shortest
check_double( -1.2345e-22, "-1.2345e-22" ); // -1.2345e-22 -1.2345000000000001e-22 -1.2345e-22
check_double( -1.2345e-21, "-1.2345e-21" ); // -1.2345e-21 -1.2345000000000001e-21 -1.2345e-21
check_double( -1.2345e-20, "-1.2345e-20" ); // -1.2345e-20 -1.2345e-20 -1.2345e-20
check_double( -1.2345e-19, "-1.2345e-19" ); // -1.2345e-19 -1.2345000000000001e-19 -1.2345e-19
check_double( -1.2345e-18, "-1.2345e-18" ); // -1.2345e-18 -1.2345000000000001e-18 -1.2345e-18
check_double( -1.2345e-17, "-1.2345e-17" ); // -1.2345e-17 -1.2345e-17 -1.2345e-17
check_double( -1.2345e-16, "-1.2345e-16" ); // -1.2345e-16 -1.2344999999999999e-16 -1.2345e-16
check_double( -1.2345e-15, "-1.2345e-15" ); // -1.2345e-15 -1.2345e-15 -1.2345e-15
check_double( -1.2345e-14, "-1.2345e-14" ); // -1.2345e-14 -1.2345e-14 -1.2345e-14
check_double( -1.2345e-13, "-1.2345e-13" ); // -1.2345e-13 -1.2344999999999999e-13 -1.2345e-13
check_double( -1.2345e-12, "-1.2345e-12" ); // -1.2345e-12 -1.2345e-12 -1.2345e-12
check_double( -1.2345e-11, "-1.2345e-11" ); // -1.2345e-11 -1.2345e-11 -1.2345e-11
check_double( -1.2345e-10, "-1.2345e-10" ); // -1.2345e-10 -1.2345e-10 -1.2345e-10
check_double( -1.2345e-9, "-1.2345e-09" ); // -1.2345e-09 -1.2345e-09 -1.2345e-9
check_double( -1.2345e-8, "-1.2345e-08" ); // -1.2345e-08 -1.2345000000000001e-08 -1.2345e-8
check_double( -1.2345e-7, "-1.2345e-07" ); // -1.2345e-07 -1.2345000000000001e-07 -1.2345e-7
check_double( -1.2345e-6, "-1.2345e-06" ); // -1.2345e-06 -1.2345e-06 -1.2345e-6
check_double( -1.2345e-5, "-1.2345e-05" ); // -1.2345e-05 -1.2345e-05 -1.2345e-5
check_double( -1.2345e-4, "-0.00012345" ); // -0.00012345 -0.00012344999999999999 -0.00012345
check_double( -1.2345e-3, "-0.0012345" ); // -0.0012345 -0.0012344999999999999 -0.0012345
check_double( -1.2345e-2, "-0.012345" ); // -0.012345 -0.012345 -0.012345
check_double( -1.2345e-1, "-0.12345" ); // -0.12345 -0.12345 -0.12345
check_double( -0.0, "-0.0" ); // -0 -0 -0
check_double( 0.0, "0.0" ); // 0 0 0
check_double( 1.2345e+0, "1.2345" ); // 1.2345 1.2344999999999999 1.2345
check_double( 1.2345e+1, "12.345" ); // 12.345 12.345000000000001 12.345
check_double( 1.2345e+2, "123.45" ); // 123.45 123.45 123.45
check_double( 1.2345e+3, "1234.5" ); // 1234.5 1234.5 1234.5
check_double( 1.2345e+4, "12345.0" ); // 12345 12345 12345
check_double( 1.2345e+5, "123450.0" ); // 123450 123450 123450
check_double( 1.2345e+6, "1234500.0" ); // 1234500 1234500 1234500
check_double( 1.2345e+7, "12345000.0" ); // 12345000 12345000 12345000
check_double( 1.2345e+8, "123450000.0" ); // 123450000 123450000 123450000
check_double( 1.2345e+9, "1234500000.0" ); // 1234500000 1234500000 1234500000
check_double( 1.2345e+10, "12345000000.0" ); // 12345000000 12345000000 12345000000
check_double( 1.2345e+11, "123450000000.0" ); // 123450000000 123450000000 123450000000
check_double( 1.2345e+12, "1234500000000.0" ); // 1234500000000 1234500000000 1234500000000
check_double( 1.2345e+13, "12345000000000.0" ); // 12345000000000 12345000000000 12345000000000
check_double( 1.2345e+14, "123450000000000.0" ); // 123450000000000 123450000000000 123450000000000
check_double( 1.2345e+15, "1.2345e+15" ); // 1.2345e+15 1234500000000000 1.2345e15
check_double( 1.2345e+16, "1.2345e+16" ); // 1.2345e+16 12345000000000000 1.2345e16
check_double( 1.2345e+17, "1.2345e+17" ); // 1.2345e+17 1.2345e+17 1.2345e17
check_double( 1.2345e+18, "1.2345e+18" ); // 1.2345e+18 1.2345e+18 1.2345e18
check_double( 1.2345e+19, "1.2345e+19" ); // 1.2345e+19 1.2345e+19 1.2345e19
check_double( 1.2345e+20, "1.2345e+20" ); // 1.2345e+20 1.2345e+20 1.2345e20
check_double( 1.2345e+21, "1.2344999999999999e+21" ); // 1.2345e+21 1.2344999999999999e+21 1.2345e21
check_double( 1.2345e+22, "1.2345e+22" ); // 1.2345e+22 1.2345e+22 1.2345e22
check_double(-1.2345e-22, "-1.2345e-22"); // -1.2345e-22 -1.2345000000000001e-22 -1.2345e-22
check_double(-1.2345e-21, "-1.2345e-21"); // -1.2345e-21 -1.2345000000000001e-21 -1.2345e-21
check_double(-1.2345e-20, "-1.2345e-20"); // -1.2345e-20 -1.2345e-20 -1.2345e-20
check_double(-1.2345e-19, "-1.2345e-19"); // -1.2345e-19 -1.2345000000000001e-19 -1.2345e-19
check_double(-1.2345e-18, "-1.2345e-18"); // -1.2345e-18 -1.2345000000000001e-18 -1.2345e-18
check_double(-1.2345e-17, "-1.2345e-17"); // -1.2345e-17 -1.2345e-17 -1.2345e-17
check_double(-1.2345e-16, "-1.2345e-16"); // -1.2345e-16 -1.2344999999999999e-16 -1.2345e-16
check_double(-1.2345e-15, "-1.2345e-15"); // -1.2345e-15 -1.2345e-15 -1.2345e-15
check_double(-1.2345e-14, "-1.2345e-14"); // -1.2345e-14 -1.2345e-14 -1.2345e-14
check_double(-1.2345e-13, "-1.2345e-13"); // -1.2345e-13 -1.2344999999999999e-13 -1.2345e-13
check_double(-1.2345e-12, "-1.2345e-12"); // -1.2345e-12 -1.2345e-12 -1.2345e-12
check_double(-1.2345e-11, "-1.2345e-11"); // -1.2345e-11 -1.2345e-11 -1.2345e-11
check_double(-1.2345e-10, "-1.2345e-10"); // -1.2345e-10 -1.2345e-10 -1.2345e-10
check_double(-1.2345e-9, "-1.2345e-09"); // -1.2345e-09 -1.2345e-09 -1.2345e-9
check_double(-1.2345e-8, "-1.2345e-08"); // -1.2345e-08 -1.2345000000000001e-08 -1.2345e-8
check_double(-1.2345e-7, "-1.2345e-07"); // -1.2345e-07 -1.2345000000000001e-07 -1.2345e-7
check_double(-1.2345e-6, "-1.2345e-06"); // -1.2345e-06 -1.2345e-06 -1.2345e-6
check_double(-1.2345e-5, "-1.2345e-05"); // -1.2345e-05 -1.2345e-05 -1.2345e-5
check_double(-1.2345e-4, "-0.00012345"); // -0.00012345 -0.00012344999999999999 -0.00012345
check_double(-1.2345e-3, "-0.0012345"); // -0.0012345 -0.0012344999999999999 -0.0012345
check_double(-1.2345e-2, "-0.012345"); // -0.012345 -0.012345 -0.012345
check_double(-1.2345e-1, "-0.12345"); // -0.12345 -0.12345 -0.12345
check_double(-0.0, "-0.0"); // -0 -0 -0
check_double(0.0, "0.0"); // 0 0 0
check_double(1.2345e+0, "1.2345"); // 1.2345 1.2344999999999999 1.2345
check_double(1.2345e+1, "12.345"); // 12.345 12.345000000000001 12.345
check_double(1.2345e+2, "123.45"); // 123.45 123.45 123.45
check_double(1.2345e+3, "1234.5"); // 1234.5 1234.5 1234.5
check_double(1.2345e+4, "12345.0"); // 12345 12345 12345
check_double(1.2345e+5, "123450.0"); // 123450 123450 123450
check_double(1.2345e+6, "1234500.0"); // 1234500 1234500 1234500
check_double(1.2345e+7, "12345000.0"); // 12345000 12345000 12345000
check_double(1.2345e+8, "123450000.0"); // 123450000 123450000 123450000
check_double(1.2345e+9, "1234500000.0"); // 1234500000 1234500000 1234500000
check_double(1.2345e+10, "12345000000.0"); // 12345000000 12345000000 12345000000
check_double(1.2345e+11, "123450000000.0"); // 123450000000 123450000000 123450000000
check_double(1.2345e+12, "1234500000000.0"); // 1234500000000 1234500000000 1234500000000
check_double(1.2345e+13, "12345000000000.0"); // 12345000000000 12345000000000 12345000000000
check_double(1.2345e+14, "123450000000000.0"); // 123450000000000 123450000000000 123450000000000
check_double(1.2345e+15, "1.2345e+15"); // 1.2345e+15 1234500000000000 1.2345e15
check_double(1.2345e+16, "1.2345e+16"); // 1.2345e+16 12345000000000000 1.2345e16
check_double(1.2345e+17, "1.2345e+17"); // 1.2345e+17 1.2345e+17 1.2345e17
check_double(1.2345e+18, "1.2345e+18"); // 1.2345e+18 1.2345e+18 1.2345e18
check_double(1.2345e+19, "1.2345e+19"); // 1.2345e+19 1.2345e+19 1.2345e19
check_double(1.2345e+20, "1.2345e+20"); // 1.2345e+20 1.2345e+20 1.2345e20
check_double(1.2345e+21, "1.2344999999999999e+21"); // 1.2345e+21 1.2344999999999999e+21 1.2345e21
check_double(1.2345e+22, "1.2345e+22"); // 1.2345e+22 1.2345e+22 1.2345e22
}
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;
CHECK(j.dump() == expected);
};
+411 -257
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -17,7 +17,7 @@ TEST_CASE("user-defined string literals")
SECTION("using namespace nlohmann::literals::json_literals")
{
using namespace nlohmann::literals::json_literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::literals::json_literals; // NOLINT(google-build-using-namespace)
CHECK(R"({"foo": "bar", "baz": 42})"_json == j_expected);
CHECK("/foo/bar"_json_pointer == ptr_expected);
@@ -25,7 +25,7 @@ TEST_CASE("user-defined string literals")
SECTION("using namespace nlohmann::json_literals")
{
using namespace nlohmann::json_literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::json_literals; // NOLINT(google-build-using-namespace)
CHECK(R"({"foo": "bar", "baz": 42})"_json == j_expected);
CHECK("/foo/bar"_json_pointer == ptr_expected);
@@ -33,7 +33,7 @@ TEST_CASE("user-defined string literals")
SECTION("using namespace nlohmann::literals")
{
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
CHECK(R"({"foo": "bar", "baz": 42})"_json == j_expected);
CHECK("/foo/bar"_json_pointer == ptr_expected);
@@ -41,7 +41,7 @@ TEST_CASE("user-defined string literals")
SECTION("using namespace nlohmann")
{
using namespace nlohmann; // NOLINT(google-build-using-namespace)
using namespace nlohmann; // NOLINT(google-build-using-namespace)
CHECK(R"({"foo": "bar", "baz": 42})"_json == j_expected);
CHECK("/foo/bar"_json_pointer == ptr_expected);
+113 -106
View File
@@ -15,7 +15,7 @@ DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept")
#include <nlohmann/json.hpp>
using nlohmann::json;
#ifdef JSON_TEST_NO_GLOBAL_UDLS
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
#endif
#include <map>
@@ -23,8 +23,7 @@ using nlohmann::json;
#include <string>
#include <utility>
namespace udt
{
namespace udt {
enum class country
{
china,
@@ -35,19 +34,25 @@ enum class country
struct age
{
int m_val;
age(int rhs = 0) : m_val(rhs) {}
age(int rhs = 0)
: m_val(rhs)
{}
};
struct name
{
std::string m_val;
name(std::string rhs = "") : m_val(std::move(rhs)) {}
name(std::string rhs = "")
: m_val(std::move(rhs))
{}
};
struct address
{
std::string m_val;
address(std::string rhs = "") : m_val(std::move(rhs)) {}
address(std::string rhs = "")
: m_val(std::move(rhs))
{}
};
struct person
@@ -56,7 +61,11 @@ struct person
name m_name{};
country m_country{};
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
@@ -64,7 +73,10 @@ struct contact
person m_person{};
address m_address{};
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
@@ -72,27 +84,29 @@ struct contact_book
name m_book_name{};
std::vector<contact> m_contacts{};
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
// to_json methods
namespace udt
{
namespace udt {
// templates because of the custom_json tests (see below)
template <typename BasicJsonType>
template<typename BasicJsonType>
static void to_json(BasicJsonType& j, age a)
{
j = a.m_val;
}
template <typename BasicJsonType>
template<typename BasicJsonType>
static void to_json(BasicJsonType& j, const name& n)
{
j = n.m_val;
}
template <typename BasicJsonType>
template<typename BasicJsonType>
static void to_json(BasicJsonType& j, country c)
{
switch (c)
@@ -111,7 +125,7 @@ static void to_json(BasicJsonType& j, country c)
}
}
template <typename BasicJsonType>
template<typename BasicJsonType>
static void to_json(BasicJsonType& j, const person& p)
{
j = BasicJsonType{{"age", p.m_age}, {"name", p.m_name}, {"country", p.m_country}};
@@ -164,40 +178,38 @@ static bool operator==(const contact_book& lhs, const contact_book& rhs)
return std::tie(lhs.m_book_name, lhs.m_contacts) ==
std::tie(rhs.m_book_name, rhs.m_contacts);
}
} // namespace udt
} // namespace udt
// from_json methods
namespace udt
{
template <typename BasicJsonType>
namespace udt {
template<typename BasicJsonType>
static void from_json(const BasicJsonType& j, age& a)
{
a.m_val = j.template get<int>();
}
template <typename BasicJsonType>
template<typename BasicJsonType>
static void from_json(const BasicJsonType& j, name& n)
{
n.m_val = j.template get<std::string>();
}
template <typename BasicJsonType>
template<typename BasicJsonType>
static void from_json(const BasicJsonType& j, country& c)
{
const auto str = j.template get<std::string>();
const std::map<std::string, country> m =
{
{"中华人民共和国", country::china},
{"France", country::france},
{"Российская Федерация", country::russia}
};
{
{"中华人民共和国", country::china},
{"France", country::france},
{"Российская Федерация", country::russia}};
const auto it = m.find(str);
// TODO(nlohmann) test exceptions
c = it->second;
}
template <typename BasicJsonType>
template<typename BasicJsonType>
static void from_json(const BasicJsonType& j, person& p)
{
p.m_age = j["age"].template get<age>();
@@ -221,16 +233,13 @@ static void from_json(const nlohmann::json& j, contact_book& cb)
cb.m_book_name = j["name"].get<name>();
cb.m_contacts = j["contacts"].get<std::vector<contact>>();
}
} // namespace udt
} // namespace udt
TEST_CASE("basic usage" * doctest::test_suite("udt"))
{
// a bit narcissistic maybe :) ?
const udt::age a
{
23
};
const udt::age a{
23};
const udt::name n{"theo"};
const udt::country c{udt::country::france};
const udt::person sfinae_addict{a, n, c};
@@ -252,7 +261,6 @@ TEST_CASE("basic usage" * doctest::test_suite("udt"))
CHECK(
json(book) ==
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")
@@ -326,19 +334,19 @@ TEST_CASE("basic usage" * doctest::test_suite("udt"))
}
}
namespace udt
{
namespace udt {
struct legacy_type
{
std::string number{};
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
namespace nlohmann
{
template <typename T>
namespace nlohmann {
template<typename T>
struct adl_serializer<std::shared_ptr<T>>
{
static void to_json(json& j, const std::shared_ptr<T>& opt)
@@ -361,12 +369,12 @@ struct adl_serializer<std::shared_ptr<T>>
}
else
{
opt.reset(new T(j.get<T>())); // NOLINT(cppcoreguidelines-owning-memory)
opt.reset(new T(j.get<T>())); // NOLINT(cppcoreguidelines-owning-memory)
}
}
};
template <>
template<>
struct adl_serializer<udt::legacy_type>
{
static void to_json(json& j, const udt::legacy_type& l)
@@ -379,7 +387,7 @@ struct adl_serializer<udt::legacy_type>
l.number = std::to_string(j.get<int>());
}
};
} // namespace nlohmann
} // namespace nlohmann
TEST_CASE("adl_serializer specialization" * doctest::test_suite("udt"))
{
@@ -392,7 +400,7 @@ TEST_CASE("adl_serializer specialization" * doctest::test_suite("udt"))
json j = optPerson;
CHECK(j.is_null());
optPerson.reset(new udt::person{{42}, {"John Doe"}, udt::country::russia}); // NOLINT(cppcoreguidelines-owning-memory,modernize-make-shared)
optPerson.reset(new udt::person{{42}, {"John Doe"}, udt::country::russia}); // NOLINT(cppcoreguidelines-owning-memory,modernize-make-shared)
j = optPerson;
CHECK_FALSE(j.is_null());
@@ -433,9 +441,8 @@ TEST_CASE("adl_serializer specialization" * doctest::test_suite("udt"))
}
}
namespace nlohmann
{
template <>
namespace nlohmann {
template<>
struct adl_serializer<std::vector<float>>
{
using type = std::vector<float>;
@@ -455,20 +462,19 @@ struct adl_serializer<std::vector<float>>
return {4.0, 5.0, 6.0};
}
};
} // namespace nlohmann
} // namespace nlohmann
TEST_CASE("even supported types can be specialized" * doctest::test_suite("udt"))
{
json const j = std::vector<float> {1.0, 2.0, 3.0};
json const j = std::vector<float>{1.0, 2.0, 3.0};
CHECK(j.dump() == R"("hijacked!")");
auto f = j.get<std::vector<float>>();
// the single argument from_json method is preferred
CHECK((f == std::vector<float> {4.0, 5.0, 6.0}));
CHECK((f == std::vector<float>{4.0, 5.0, 6.0}));
}
namespace nlohmann
{
template <typename T>
namespace nlohmann {
template<typename T>
struct adl_serializer<std::unique_ptr<T>>
{
static void to_json(json& j, const std::unique_ptr<T>& opt)
@@ -494,7 +500,7 @@ struct adl_serializer<std::unique_ptr<T>>
return std::unique_ptr<T>(new T(j.get<T>()));
}
};
} // namespace nlohmann
} // namespace nlohmann
TEST_CASE("Non-copyable types" * doctest::test_suite("udt"))
{
@@ -505,7 +511,7 @@ TEST_CASE("Non-copyable types" * doctest::test_suite("udt"))
json j = optPerson;
CHECK(j.is_null());
optPerson.reset(new udt::person{{42}, {"John Doe"}, udt::country::russia}); // NOLINT(cppcoreguidelines-owning-memory,modernize-make-unique)
optPerson.reset(new udt::person{{42}, {"John Doe"}, udt::country::russia}); // NOLINT(cppcoreguidelines-owning-memory,modernize-make-unique)
j = optPerson;
CHECK_FALSE(j.is_null());
@@ -530,14 +536,16 @@ TEST_CASE("Non-copyable types" * doctest::test_suite("udt"))
// custom serializer - advanced usage
// pack structs that are pod-types (but not scalar types)
// relies on adl for any other type
template <typename T, typename = void>
template<typename T, typename = void>
struct pod_serializer
{
// use adl for non-pods, or scalar types
template <
typename BasicJsonType, typename U = T,
typename std::enable_if <
!(std::is_pod<U>::value && std::is_class<U>::value), int >::type = 0 >
template<
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)
{
using nlohmann::from_json;
@@ -545,10 +553,8 @@ struct pod_serializer
}
// special behaviour for pods
template < 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)
template<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)
{
std::uint64_t value = 0;
// The following block is no longer relevant in this serializer, make another one that shows the issue
@@ -566,34 +572,33 @@ struct pod_serializer
// calling get calls from_json, for now, we cannot do this in custom
// serializers
nlohmann::from_json(j, value);
auto* bytes = static_cast<char*>(static_cast<void*>(&value)); // NOLINT(bugprone-casting-through-void)
auto* bytes = static_cast<char*>(static_cast<void*>(&value)); // NOLINT(bugprone-casting-through-void)
std::memcpy(&t, bytes, sizeof(value));
}
template <
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)
template<
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)
{
using nlohmann::to_json;
to_json(j, t);
}
template < 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) noexcept
template<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) 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)
std::uint64_t value = 0;
std::memcpy(&value, bytes, sizeof(value));
nlohmann::to_json(j, value);
}
};
namespace udt
{
namespace udt {
struct small_pod
{
int begin;
@@ -605,16 +610,18 @@ struct non_pod
{
std::string s{};
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>
static void to_json(BasicJsonType& j, const non_pod& np)
{
j = np.s;
}
template <typename BasicJsonType>
template<typename BasicJsonType>
static void from_json(const BasicJsonType& j, non_pod& np)
{
np.s = j.template get<std::string>();
@@ -626,7 +633,7 @@ static bool operator==(small_pod lhs, small_pod rhs) noexcept
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
{
return lhs.s == rhs.s;
}
@@ -635,13 +642,12 @@ static std::ostream& operator<<(std::ostream& os, small_pod l)
{
return os << "begin: " << l.begin << ", middle: " << l.middle << ", end: " << l.end;
}
} // namespace udt
} // namespace udt
TEST_CASE("custom serializer for pods" * doctest::test_suite("udt"))
{
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};
custom_json const j = p;
@@ -656,12 +662,12 @@ TEST_CASE("custom serializer for pods" * doctest::test_suite("udt"))
CHECK(np == np2);
}
template <typename T, typename>
template<typename T, typename>
struct another_adl_serializer;
using custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, another_adl_serializer>;
template <typename T, typename>
template<typename T, typename>
struct another_adl_serializer
{
static void from_json(const custom_json& j, T& t)
@@ -718,7 +724,7 @@ TEST_CASE("different basic_json types conversions")
{
json const j = {1, 2, 3};
custom_json const cj = j;
CHECK((cj == std::vector<int> {1, 2, 3}));
CHECK((cj == std::vector<int>{1, 2, 3}));
}
SECTION("integer")
@@ -775,42 +781,43 @@ TEST_CASE("different basic_json types conversions")
}
}
namespace
{
namespace {
struct incomplete;
// std::is_constructible is broken on macOS' libc++
// use the cppreference implementation
template <typename T, typename = void>
struct is_constructible_patched : std::false_type {};
template<typename T, typename = void>
struct is_constructible_patched : std::false_type
{};
template <typename T>
struct is_constructible_patched<T, decltype(void(json(std::declval<T>())))> : std::true_type {};
} // namespace
template<typename T>
struct is_constructible_patched<T, decltype(void(json(std::declval<T>())))> : std::true_type
{};
} // namespace
TEST_CASE("an incomplete type does not trigger a compiler error in non-evaluated context" * doctest::test_suite("udt"))
{
static_assert(!is_constructible_patched<json, incomplete>::value, "");
}
namespace
{
namespace {
class Evil
{
public:
Evil() = default;
template <typename T>
Evil(T t) : m_i(sizeof(t))
template<typename 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
}
int m_i = 0;
};
void from_json(const json& /*unused*/, Evil& /*unused*/) {}
} // namespace
} // namespace
TEST_CASE("Issue #924")
{
@@ -827,17 +834,17 @@ TEST_CASE("Issue #924")
TEST_CASE("Issue #1237")
{
struct non_convertible_type {};
struct non_convertible_type
{};
static_assert(!std::is_convertible<json, non_convertible_type>::value, "");
}
namespace
{
namespace {
class no_iterator_type
{
public:
no_iterator_type(std::initializer_list<int> l)
: _v(l)
: _v(l)
{}
std::vector<int>::const_iterator begin() const
+86 -98
View File
@@ -6,15 +6,14 @@
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#include "doctest_compatibility.h"
#include <string>
#include <vector>
#include "doctest_compatibility.h"
#include <nlohmann/json.hpp>
using nlohmann::json;
namespace persons
{
namespace persons {
class person_with_private_data
{
private:
@@ -30,9 +29,9 @@ class person_with_private_data
person_with_private_data() = default;
person_with_private_data(std::string name_, int age_, json metadata_)
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
{}
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_data, age, name, metadata)
@@ -53,9 +52,9 @@ class person_with_private_data_2
person_with_private_data_2() = default;
person_with_private_data_2(std::string name_, int age_, json metadata_)
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
{}
std::string getName() const
@@ -88,9 +87,9 @@ class person_without_private_data_1
person_without_private_data_1() = default;
person_without_private_data_1(std::string name_, int age_, json metadata_)
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
{}
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_without_private_data_1, age, name, metadata)
@@ -110,9 +109,9 @@ class person_without_private_data_2
person_without_private_data_2() = default;
person_without_private_data_2(std::string name_, int age_, json metadata_)
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
{}
};
@@ -132,9 +131,9 @@ class person_without_private_data_3
person_without_private_data_3() = default;
person_without_private_data_3(std::string name_, int age_, json metadata_)
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
{}
std::string getName() const
@@ -158,32 +157,32 @@ class person_with_private_alphabet
public:
bool operator==(const person_with_private_alphabet& other) const
{
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 &&
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;
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 &&
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:
@@ -221,32 +220,32 @@ class person_with_public_alphabet
public:
bool operator==(const person_with_public_alphabet& other) const
{
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 &&
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;
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 &&
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;
@@ -291,8 +290,8 @@ class person_without_default_constructor_1
}
person_without_default_constructor_1(std::string name_, int age_)
: name{std::move(name_)}
, age{age_}
: name{std::move(name_)}
, age{age_}
{}
NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(person_without_default_constructor_1, name, age)
@@ -310,19 +309,16 @@ class person_without_default_constructor_2
}
person_without_default_constructor_2(std::string name_, int age_)
: name{std::move(name_)}
, age{age_}
: name{std::move(name_)}
, age{age_}
{}
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(person_without_default_constructor_2, name, age)
} // namespace persons
} // namespace persons
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
persons::person_with_private_data,
persons::person_without_private_data_1,
persons::person_without_private_data_2)
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T, persons::person_with_private_data, persons::person_without_private_data_1, persons::person_without_private_data_2)
{
SECTION("person")
{
@@ -345,9 +341,7 @@ 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,
persons::person_with_private_data_2,
persons::person_without_private_data_3)
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_without_private_data_3)
{
SECTION("person with default values")
{
@@ -379,15 +373,13 @@ 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,
persons::person_with_private_alphabet,
persons::person_with_public_alphabet)
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_public_alphabet)
{
SECTION("alphabet")
{
{
T obj1;
nlohmann::json const j = obj1; //via json object
nlohmann::json const j = obj1; //via json object
T obj2;
j.get_to(obj2);
bool ok = (obj1 == obj2);
@@ -396,7 +388,7 @@ TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/priv
{
T obj1;
nlohmann::json const j1 = obj1; //via json string
nlohmann::json const j1 = obj1; //via json string
std::string const s = j1.dump();
nlohmann::json const j2 = nlohmann::json::parse(s);
T obj2;
@@ -407,7 +399,7 @@ TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/priv
{
T obj1;
nlohmann::json const j1 = obj1; //via msgpack
nlohmann::json const j1 = obj1; //via msgpack
std::vector<uint8_t> const buf = nlohmann::json::to_msgpack(j1);
nlohmann::json const j2 = nlohmann::json::from_msgpack(buf);
T obj2;
@@ -418,7 +410,7 @@ TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/priv
{
T obj1;
nlohmann::json const j1 = obj1; //via bson
nlohmann::json const j1 = obj1; //via bson
std::vector<uint8_t> const buf = nlohmann::json::to_bson(j1);
nlohmann::json const j2 = nlohmann::json::from_bson(buf);
T obj2;
@@ -429,7 +421,7 @@ TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/priv
{
T obj1;
nlohmann::json const j1 = obj1; //via cbor
nlohmann::json const j1 = obj1; //via cbor
std::vector<uint8_t> const buf = nlohmann::json::to_cbor(j1);
nlohmann::json const j2 = nlohmann::json::from_cbor(buf);
T obj2;
@@ -440,7 +432,7 @@ TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/priv
{
T obj1;
nlohmann::json const j1 = obj1; //via ubjson
nlohmann::json const j1 = obj1; //via ubjson
std::vector<uint8_t> const buf = nlohmann::json::to_ubjson(j1);
nlohmann::json const j2 = nlohmann::json::from_ubjson(buf);
T obj2;
@@ -451,9 +443,7 @@ 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,
persons::person_without_default_constructor_1,
persons::person_without_default_constructor_2)
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_2)
{
SECTION("person")
{
@@ -463,11 +453,9 @@ TEST_CASE_TEMPLATE("Serialization of non-default-constructible classes via NLOHM
CHECK(json(person).dump() == "{\"age\":1,\"name\":\"Erik\"}");
// serialization of a container with objects
std::vector<T> const two_persons
{
std::vector<T> const two_persons{
{"Erik", 1},
{"Kyle", 2}
};
{"Kyle", 2}};
CHECK(json(two_persons).dump() == "[{\"age\":1,\"name\":\"Erik\"},{\"age\":2,\"name\":\"Kyle\"}]");
}
}
+7 -9
View File
@@ -13,18 +13,17 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#include <fstream>
#include <sstream>
#include <iomanip>
#include "make_test_data_available.hpp"
#include <fstream>
#include <iomanip>
#include <sstream>
TEST_CASE("Unicode (1/5)" * doctest::skip())
{
SECTION("\\uxxxx sequences")
{
// 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
// reverse solidus, followed by the lowercase letter u, followed
// by four hexadecimal digits that encode the character's code
@@ -102,7 +101,7 @@ TEST_CASE("Unicode (1/5)" * doctest::skip())
}
}
#if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)
#if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)
SECTION("incorrect sequences")
{
SECTION("high surrogate without low surrogate")
@@ -223,8 +222,7 @@ TEST_CASE("Unicode (1/5)" * doctest::skip())
}
}
namespace
{
namespace {
void roundtrip(bool success_expected, const std::string& s);
void roundtrip(bool success_expected, const std::string& s)
@@ -265,7 +263,7 @@ void roundtrip(bool success_expected, const std::string& s)
CHECK_THROWS_AS(_ = json::parse(ps), json::parse_error&);
}
}
} // namespace
} // namespace
TEST_CASE("Markus Kuhn's UTF-8 decoder capability and stress test")
{
+7 -8
View File
@@ -14,18 +14,17 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#include <fstream>
#include <sstream>
#include <iostream>
#include <iomanip>
#include "make_test_data_available.hpp"
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
// this test suite uses static variables with non-trivial destructors
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
namespace
{
namespace {
extern size_t calls;
size_t calls = 0;
@@ -123,7 +122,7 @@ void check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte
{
if (++calls % 100000 == 0)
{
std::cout << calls << " of 455355 UTF-8 strings checked" << std::endl; // NOLINT(performance-avoid-endl)
std::cout << calls << " of 455355 UTF-8 strings checked" << std::endl; // NOLINT(performance-avoid-endl)
}
static std::string json_string;
@@ -164,7 +163,7 @@ void check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte
CHECK_THROWS_AS(_ = json::parse(json_string), json::parse_error&);
}
}
} // namespace
} // namespace
TEST_CASE("Unicode (2/5)" * doctest::skip())
{
+7 -8
View File
@@ -14,18 +14,17 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#include <fstream>
#include <sstream>
#include <iostream>
#include <iomanip>
#include "make_test_data_available.hpp"
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
// this test suite uses static variables with non-trivial destructors
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
namespace
{
namespace {
extern size_t calls;
size_t calls = 0;
@@ -123,7 +122,7 @@ void check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte
{
if (++calls % 100000 == 0)
{
std::cout << calls << " of 1641521 UTF-8 strings checked" << std::endl; // NOLINT(performance-avoid-endl)
std::cout << calls << " of 1641521 UTF-8 strings checked" << std::endl; // NOLINT(performance-avoid-endl)
}
static std::string json_string;
@@ -164,7 +163,7 @@ void check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte
CHECK_THROWS_AS(_ = json::parse(json_string), json::parse_error&);
}
}
} // namespace
} // namespace
TEST_CASE("Unicode (3/5)" * doctest::skip())
{
+7 -8
View File
@@ -14,18 +14,17 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#include <fstream>
#include <sstream>
#include <iostream>
#include <iomanip>
#include "make_test_data_available.hpp"
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
// this test suite uses static variables with non-trivial destructors
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
namespace
{
namespace {
extern size_t calls;
size_t calls = 0;
@@ -123,7 +122,7 @@ void check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte
{
if (++calls % 100000 == 0)
{
std::cout << calls << " of 5517507 UTF-8 strings checked" << std::endl; // NOLINT(performance-avoid-endl)
std::cout << calls << " of 5517507 UTF-8 strings checked" << std::endl; // NOLINT(performance-avoid-endl)
}
static std::string json_string;
@@ -164,7 +163,7 @@ void check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte
CHECK_THROWS_AS(_ = json::parse(json_string), json::parse_error&);
}
}
} // namespace
} // namespace
TEST_CASE("Unicode (4/5)" * doctest::skip())
{
+7 -8
View File
@@ -14,18 +14,17 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#include <fstream>
#include <sstream>
#include <iostream>
#include <iomanip>
#include "make_test_data_available.hpp"
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
// this test suite uses static variables with non-trivial destructors
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
namespace
{
namespace {
extern size_t calls;
size_t calls = 0;
@@ -123,7 +122,7 @@ void check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte
{
if (++calls % 100000 == 0)
{
std::cout << calls << " of 1246225 UTF-8 strings checked" << std::endl; // NOLINT(performance-avoid-endl)
std::cout << calls << " of 1246225 UTF-8 strings checked" << std::endl; // NOLINT(performance-avoid-endl)
}
static std::string json_string;
@@ -164,7 +163,7 @@ void check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte
CHECK_THROWS_AS(_ = json::parse(json_string), json::parse_error&);
}
}
} // namespace
} // namespace
TEST_CASE("Unicode (5/5)" * doctest::skip())
{
+6 -9
View File
@@ -13,8 +13,7 @@ using nlohmann::json;
#include <list>
namespace
{
namespace {
TEST_CASE("Use arbitrary stdlib container")
{
std::string raw_data = "[1,2,3,4]";
@@ -39,19 +38,17 @@ const char* begin(const MyContainer& c)
const char* end(const MyContainer& c)
{
return c.data + strlen(c.data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return c.data + strlen(c.data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
}
TEST_CASE("Custom container non-member begin/end")
{
const MyContainer data{"[1,2,3,4]"};
json as_json = json::parse(data);
CHECK(as_json.at(0) == 1);
CHECK(as_json.at(1) == 2);
CHECK(as_json.at(2) == 3);
CHECK(as_json.at(3) == 4);
}
TEST_CASE("Custom container member begin/end")
@@ -67,7 +64,7 @@ TEST_CASE("Custom container member begin/end")
const char* end() const
{
return data + strlen(data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return data + strlen(data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
}
};
@@ -93,7 +90,7 @@ TEST_CASE("Custom iterator")
MyIterator& operator++()
{
++ptr; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
++ptr; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return *this;
}
@@ -118,7 +115,7 @@ TEST_CASE("Custom iterator")
CHECK(std::is_same<MyIterator::iterator_category, std::input_iterator_tag>::value);
const MyIterator begin{raw_data};
const MyIterator end{raw_data + strlen(raw_data)}; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
const MyIterator end{raw_data + strlen(raw_data)}; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
json as_json = json::parse(begin, end);
CHECK(as_json.at(0) == 1);
@@ -127,4 +124,4 @@ TEST_CASE("Custom iterator")
CHECK(as_json.at(3) == 4);
}
} // namespace
} // namespace
+2 -3
View File
@@ -13,8 +13,7 @@ using nlohmann::json;
// ICPC errors out on multibyte character sequences in source files
#ifndef __INTEL_COMPILER
namespace
{
namespace {
bool wstring_is_utf16();
bool wstring_is_utf16()
{
@@ -32,7 +31,7 @@ bool u32string_is_utf32()
{
return (std::u32string(U"💩") == std::u32string(U"\U0001F4A9"));
}
} // namespace
} // namespace
TEST_CASE("wide strings")
{