diff options
| author | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:42:50 +0300 |
|---|---|---|
| committer | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:42:50 +0300 |
| commit | 5fad10f89c485cfdc7b99011f07609f8871160d4 (patch) | |
| tree | 1860b39753b652dfe54d3cbbc80c875f40198d1f /json4cpp/tests/src/unit-algorithms.cpp | |
| parent | 292baed7ac0cf84263263966ed32ed113cae857f (diff) | |
| parent | 9a737481aed085fd289f82dff1fa8c3c66627a7e (diff) | |
| download | Project-Tick-5fad10f89c485cfdc7b99011f07609f8871160d4.tar.gz Project-Tick-5fad10f89c485cfdc7b99011f07609f8871160d4.zip | |
Add 'json4cpp/' from commit '9a737481aed085fd289f82dff1fa8c3c66627a7e'
git-subtree-dir: json4cpp
git-subtree-mainline: 292baed7ac0cf84263263966ed32ed113cae857f
git-subtree-split: 9a737481aed085fd289f82dff1fa8c3c66627a7e
Diffstat (limited to 'json4cpp/tests/src/unit-algorithms.cpp')
| -rw-r--r-- | json4cpp/tests/src/unit-algorithms.cpp | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/json4cpp/tests/src/unit-algorithms.cpp b/json4cpp/tests/src/unit-algorithms.cpp new file mode 100644 index 0000000000..0aac52f0bc --- /dev/null +++ b/json4cpp/tests/src/unit-algorithms.cpp @@ -0,0 +1,365 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ (supporting code) +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me> +// SPDX-License-Identifier: MIT + +#include "doctest_compatibility.h" + +#include <algorithm> +#include <nlohmann/json.hpp> +using nlohmann::json; + +TEST_CASE("algorithms") +{ + json j_array = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz"}; + json j_object = {{"one", 1}, {"two", 2}}; + + SECTION("non-modifying sequence operations") + { + SECTION("std::all_of") + { + 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) + { + 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) + { + return value.is_string() && value.get<std::string>() == "foo"; + })); + 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) + { + return value.empty(); + })); + CHECK(std::none_of(j_object.begin(), j_object.end(), [](const json & value) + { + return value.get<int>() <= 0; + })); + } + + SECTION("std::for_each") + { + SECTION("reading") + { + int sum = 0; + + std::for_each(j_array.cbegin(), j_array.cend(), [&sum](const json & value) + { + if (value.is_number()) + { + sum += static_cast<int>(value); + } + }); + + CHECK(sum == 45); + } + + SECTION("writing") + { + auto add17 = [](json & value) + { + if (value.is_array()) + { + value.push_back(17); + } + }; + + std::for_each(j_array.begin(), j_array.end(), add17); + + CHECK(j_array[6] == json({1, 2, 3, 17})); + } + } + + SECTION("std::count") + { + CHECK(std::count(j_array.begin(), j_array.end(), json(true)) == 1); + } + + 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); + } + + SECTION("std::mismatch") + { + json j_array2 = {13, 29, 3, {{"one", 1}, {"two", 2}, {"three", 3}}, true, false, {1, 2, 3}, "foo", "baz"}; + auto res = std::mismatch(j_array.begin(), j_array.end(), j_array2.begin()); + CHECK(*res.first == json({{"one", 1}, {"two", 2}})); + CHECK(*res.second == json({{"one", 1}, {"two", 2}, {"three", 3}})); + } + + SECTION("std::equal") + { + SECTION("using operator==") + { + CHECK(std::equal(j_array.begin(), j_array.end(), j_array.begin())); + CHECK(std::equal(j_object.begin(), j_object.end(), j_object.begin())); + CHECK(!std::equal(j_array.begin(), j_array.end(), j_object.begin())); + } + + SECTION("using user-defined comparison") + { + // 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) + { + return (a.size() == b.size()); + })); + } + } + + SECTION("std::find") + { + auto it = std::find(j_array.begin(), j_array.end(), json(false)); + CHECK(std::distance(j_array.begin(), it) == 5); + } + + SECTION("std::find_if") + { + 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); + } + + SECTION("std::find_if_not") + { + 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); + } + + 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()); + } + } + + SECTION("modifying sequence operations") + { + SECTION("std::reverse") + { + std::reverse(j_array.begin(), j_array.end()); + CHECK(j_array == json({"baz", "foo", {1, 2, 3}, false, true, {{"one", 1}, {"two", 2}}, 3, 29, 13})); + } + + SECTION("std::rotate") + { + std::rotate(j_array.begin(), j_array.begin() + 1, j_array.end()); + CHECK(j_array == json({29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", 13})); + } + + SECTION("std::partition") + { + 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); + CHECK(!it[2].is_string()); + } + } + + SECTION("sorting operations") + { + SECTION("std::sort") + { + SECTION("with standard comparison") + { + json j = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", nullptr}; + std::sort(j.begin(), j.end()); + CHECK(j == json({nullptr, false, true, 3, 13, 29, {{"one", 1}, {"two", 2}}, {1, 2, 3}, "baz", "foo"})); + } + + 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) + { + return a.size() < b.size(); + }); + CHECK(j == json({nullptr, 3, {{"one", 1}, {"two", 2}}, {1, 2, 3}})); + } + + SECTION("sorting an object") + { + json j({{"one", 1}, {"two", 2}}); + CHECK_THROWS_WITH_AS(std::sort(j.begin(), j.end()), "[json.exception.invalid_iterator.209] cannot use offsets with object iterators", json::invalid_iterator&); + } + } + + SECTION("std::partial_sort") + { + json j = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", nullptr}; + std::partial_sort(j.begin(), j.begin() + 4, j.end()); + CHECK(j == json({nullptr, false, true, 3, {{"one", 1}, {"two", 2}}, 29, {1, 2, 3}, "foo", "baz", 13})); + } + } + + SECTION("set operations") + { + SECTION("std::merge") + { + { + json j1 = {2, 4, 6, 8}; + json j2 = {1, 2, 3, 5, 7}; + json j3; + + std::merge(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3)); + CHECK(j3 == json({1, 2, 2, 3, 4, 5, 6, 7, 8})); + } + } + + SECTION("std::set_difference") + { + json j1 = {1, 2, 3, 4, 5, 6, 7, 8}; + json j2 = {1, 2, 3, 5, 7}; + json j3; + + std::set_difference(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3)); + CHECK(j3 == json({4, 6, 8})); + } + + SECTION("std::set_intersection") + { + json j1 = {1, 2, 3, 4, 5, 6, 7, 8}; + json j2 = {1, 2, 3, 5, 7}; + json j3; + + std::set_intersection(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3)); + CHECK(j3 == json({1, 2, 3, 5, 7})); + } + + SECTION("std::set_union") + { + json j1 = {2, 4, 6, 8}; + json j2 = {1, 2, 3, 5, 7}; + json j3; + + std::set_union(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3)); + CHECK(j3 == json({1, 2, 3, 4, 5, 6, 7, 8})); + } + + SECTION("std::set_symmetric_difference") + { + json j1 = {2, 4, 6, 8}; + json j2 = {1, 2, 3, 5, 7}; + json j3; + + std::set_symmetric_difference(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3)); + CHECK(j3 == json({1, 3, 4, 5, 6, 7, 8})); + } + } + + SECTION("heap operations") + { + std::make_heap(j_array.begin(), j_array.end()); + CHECK(std::is_heap(j_array.begin(), j_array.end())); + std::sort_heap(j_array.begin(), j_array.end()); + CHECK(j_array == json({false, true, 3, 13, 29, {{"one", 1}, {"two", 2}}, {1, 2, 3}, "baz", "foo"})); + } + + SECTION("iota") + { + SECTION("int") + { + json json_arr = {0, 5, 2, 4, 10, 20, 30, 40, 50, 1}; + std::iota(json_arr.begin(), json_arr.end(), 0); + CHECK(json_arr == json({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})); + } + SECTION("double") + { + json json_arr = {0.5, 1.5, 1.3, 4.1, 10.2, 20.5, 30.6, 40.1, 50.22, 1.5}; + std::iota(json_arr.begin(), json_arr.end(), 0.5); + CHECK(json_arr == json({0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5})); + } + + SECTION("char") + { + json json_arr = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '0', '1'}; + std::iota(json_arr.begin(), json_arr.end(), '0'); + CHECK(json_arr == json({'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'})); + } + } + + SECTION("copy") + { + SECTION("copy without if") + { + json dest_arr; + const json source_arr = {1, 2, 3, 4}; + + std::copy(source_arr.begin(), source_arr.end(), std::back_inserter(dest_arr)); + + CHECK(dest_arr == source_arr); + } + SECTION("copy if") + { + 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) + { + return _value.get<int>() % 3 == 0; + }); + CHECK(dest_arr == json({0, 3, 6, 9, 12, 15})); + } + SECTION("copy n") + { + const json source_arr = {0, 1, 2, 3, 4, 5, 6, 7}; + json dest_arr; + const unsigned char numToCopy = 2; + + std::copy_n(source_arr.begin(), numToCopy, std::back_inserter(dest_arr)); + CHECK(dest_arr == json{0, 1}); + + } + SECTION("copy n chars") + { + const json source_arr = {'1', '2', '3', '4', '5', '6', '7'}; + json dest_arr; + const unsigned char numToCopy = 4; + + std::copy_n(source_arr.begin(), numToCopy, std::back_inserter(dest_arr)); + CHECK(dest_arr == json{'1', '2', '3', '4'}); + } + } + +} |
