summaryrefslogtreecommitdiff
path: root/json4cpp/tests/src/unit-class_iterator.cpp
diff options
context:
space:
mode:
authorMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:42:50 +0300
committerMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:42:50 +0300
commit5fad10f89c485cfdc7b99011f07609f8871160d4 (patch)
tree1860b39753b652dfe54d3cbbc80c875f40198d1f /json4cpp/tests/src/unit-class_iterator.cpp
parent292baed7ac0cf84263263966ed32ed113cae857f (diff)
parent9a737481aed085fd289f82dff1fa8c3c66627a7e (diff)
downloadProject-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-class_iterator.cpp')
-rw-r--r--json4cpp/tests/src/unit-class_iterator.cpp468
1 files changed, 468 insertions, 0 deletions
diff --git a/json4cpp/tests/src/unit-class_iterator.cpp b/json4cpp/tests/src/unit-class_iterator.cpp
new file mode 100644
index 0000000000..2303381177
--- /dev/null
+++ b/json4cpp/tests/src/unit-class_iterator.cpp
@@ -0,0 +1,468 @@
+// __ _____ _____ _____
+// __| | __| | | | 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"
+
+#define JSON_TESTS_PRIVATE
+#include <nlohmann/json.hpp>
+using nlohmann::json;
+
+template<typename Iter>
+using can_post_increment_temporary = decltype((std::declval<Iter>()++)++);
+
+template<typename Iter>
+using can_post_decrement_temporary = decltype((std::declval<Iter>()--)--);
+
+TEST_CASE("iterator class")
+{
+ SECTION("construction")
+ {
+ SECTION("constructor")
+ {
+ SECTION("null")
+ {
+ json j(json::value_t::null);
+ json::iterator const it(&j);
+ }
+
+ SECTION("object")
+ {
+ json j(json::value_t::object);
+ json::iterator const it(&j);
+ }
+
+ SECTION("array")
+ {
+ json j(json::value_t::array);
+ json::iterator const it(&j);
+ }
+ }
+
+ SECTION("copy assignment")
+ {
+ json j(json::value_t::null);
+ json::iterator const it(&j);
+ json::iterator it2(&j);
+ it2 = it;
+ }
+ }
+
+ SECTION("initialization")
+ {
+ SECTION("set_begin")
+ {
+ SECTION("null")
+ {
+ json j(json::value_t::null);
+ json::iterator it(&j);
+ it.set_begin();
+ CHECK((it == j.begin()));
+ }
+
+ SECTION("object")
+ {
+ json j(json::value_t::object);
+ json::iterator it(&j);
+ it.set_begin();
+ CHECK((it == j.begin()));
+ }
+
+ SECTION("array")
+ {
+ json j(json::value_t::array);
+ json::iterator it(&j);
+ it.set_begin();
+ CHECK((it == j.begin()));
+ }
+ }
+
+ SECTION("set_end")
+ {
+ SECTION("null")
+ {
+ json j(json::value_t::null);
+ json::iterator it(&j);
+ it.set_end();
+ CHECK((it == j.end()));
+ }
+
+ SECTION("object")
+ {
+ json j(json::value_t::object);
+ json::iterator it(&j);
+ it.set_end();
+ CHECK((it == j.end()));
+ }
+
+ SECTION("array")
+ {
+ json j(json::value_t::array);
+ json::iterator it(&j);
+ it.set_end();
+ CHECK((it == j.end()));
+ }
+ }
+ }
+
+ SECTION("element access")
+ {
+ SECTION("operator*")
+ {
+ SECTION("null")
+ {
+ json j(json::value_t::null);
+ json::iterator const it = j.begin();
+ CHECK_THROWS_WITH_AS(*it, "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&);
+ }
+
+ SECTION("number")
+ {
+ json j(17);
+ json::iterator it = j.begin();
+ CHECK(*it == json(17));
+ it = j.end();
+ CHECK_THROWS_WITH_AS(*it, "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&);
+ }
+
+ SECTION("object")
+ {
+ json j({{"foo", "bar"}});
+ json::iterator const it = j.begin();
+ CHECK(*it == json("bar"));
+ }
+
+ SECTION("array")
+ {
+ json j({1, 2, 3, 4});
+ json::iterator const it = j.begin();
+ CHECK(*it == json(1));
+ }
+ }
+
+ SECTION("operator->")
+ {
+ SECTION("null")
+ {
+ json j(json::value_t::null);
+ json::iterator const it = j.begin();
+ CHECK_THROWS_WITH_AS(std::string(it->type_name()), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&);
+ }
+
+ SECTION("number")
+ {
+ json j(17);
+ json::iterator it = j.begin();
+ CHECK(std::string(it->type_name()) == "number");
+ it = j.end();
+ CHECK_THROWS_WITH_AS(std::string(it->type_name()), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&);
+ }
+
+ SECTION("object")
+ {
+ json j({{"foo", "bar"}});
+ json::iterator const it = j.begin();
+ CHECK(std::string(it->type_name()) == "string");
+ }
+
+ SECTION("array")
+ {
+ json j({1, 2, 3, 4});
+ json::iterator const it = j.begin();
+ CHECK(std::string(it->type_name()) == "number");
+ }
+ }
+ }
+
+ SECTION("increment/decrement")
+ {
+ SECTION("post-increment")
+ {
+ SECTION("null")
+ {
+ json j(json::value_t::null);
+ json::iterator it = j.begin();
+ CHECK((it.m_it.primitive_iterator.m_it == 1));
+ it++;
+ CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
+ }
+
+ SECTION("number")
+ {
+ json j(17);
+ json::iterator it = j.begin();
+ CHECK((it.m_it.primitive_iterator.m_it == 0));
+ it++;
+ CHECK((it.m_it.primitive_iterator.m_it == 1));
+ it++;
+ CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
+ }
+
+ SECTION("object")
+ {
+ json j({{"foo", "bar"}});
+ json::iterator it = j.begin();
+ CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
+ it++;
+ CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
+ }
+
+ SECTION("array")
+ {
+ json j({1, 2, 3, 4});
+ json::iterator it = j.begin();
+ CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
+ it++;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ it++;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ it++;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ it++;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
+ }
+ }
+
+ SECTION("pre-increment")
+ {
+ SECTION("null")
+ {
+ json j(json::value_t::null);
+ json::iterator it = j.begin();
+ CHECK((it.m_it.primitive_iterator.m_it == 1));
+ ++it;
+ CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
+ }
+
+ SECTION("number")
+ {
+ json j(17);
+ json::iterator it = j.begin();
+ CHECK((it.m_it.primitive_iterator.m_it == 0));
+ ++it;
+ CHECK((it.m_it.primitive_iterator.m_it == 1));
+ ++it;
+ CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
+ }
+
+ SECTION("object")
+ {
+ json j({{"foo", "bar"}});
+ json::iterator it = j.begin();
+ CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
+ ++it;
+ CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
+ }
+
+ SECTION("array")
+ {
+ json j({1, 2, 3, 4});
+ json::iterator it = j.begin();
+ CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
+ ++it;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ ++it;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ ++it;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ ++it;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
+ }
+ }
+
+ SECTION("post-decrement")
+ {
+ SECTION("null")
+ {
+ json j(json::value_t::null);
+ json::iterator const it = j.end();
+ CHECK((it.m_it.primitive_iterator.m_it == 1));
+ }
+
+ SECTION("number")
+ {
+ json j(17);
+ json::iterator it = j.end();
+ CHECK((it.m_it.primitive_iterator.m_it == 1));
+ it--;
+ CHECK((it.m_it.primitive_iterator.m_it == 0));
+ it--;
+ CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
+ }
+
+ SECTION("object")
+ {
+ json j({{"foo", "bar"}});
+ json::iterator it = j.end();
+ CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
+ it--;
+ CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
+ }
+
+ SECTION("array")
+ {
+ json j({1, 2, 3, 4});
+ json::iterator it = j.end();
+ CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
+ it--;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ it--;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ it--;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ it--;
+ CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ }
+ }
+
+ SECTION("pre-decrement")
+ {
+ SECTION("null")
+ {
+ json j(json::value_t::null);
+ json::iterator const it = j.end();
+ CHECK((it.m_it.primitive_iterator.m_it == 1));
+ }
+
+ SECTION("number")
+ {
+ json j(17);
+ json::iterator it = j.end();
+ CHECK((it.m_it.primitive_iterator.m_it == 1));
+ --it;
+ CHECK((it.m_it.primitive_iterator.m_it == 0));
+ --it;
+ CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
+ }
+
+ SECTION("object")
+ {
+ json j({{"foo", "bar"}});
+ json::iterator it = j.end();
+ CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
+ --it;
+ CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
+ }
+
+ SECTION("array")
+ {
+ json j({1, 2, 3, 4});
+ json::iterator it = j.end();
+ CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
+ --it;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ --it;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ --it;
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ --it;
+ CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
+ CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
+ }
+ }
+ }
+ SECTION("equality-preserving")
+ {
+ SECTION("post-increment")
+ {
+ SECTION("primitive_iterator_t")
+ {
+ using Iter = nlohmann::detail::primitive_iterator_t;
+ 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);
+ }
+ 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);
+ }
+ }
+ SECTION("post-decrement")
+ {
+ SECTION("primitive_iterator_t")
+ {
+ using Iter = nlohmann::detail::primitive_iterator_t;
+ 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 );
+ }
+ 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 );
+ }
+ }
+ }
+ // prevent "accidental mutation of a temporary object"
+ SECTION("cert-dcl21-cpp")
+ {
+ using nlohmann::detail::is_detected;
+ SECTION("post-increment")
+ {
+ SECTION("primitive_iterator_t")
+ {
+ using Iter = nlohmann::detail::primitive_iterator_t;
+ CHECK_FALSE(is_detected<can_post_increment_temporary, Iter&>::value);
+ }
+ SECTION("iter_impl")
+ {
+ using Iter = nlohmann::detail::iter_impl<json>;
+ CHECK_FALSE(is_detected<can_post_increment_temporary, Iter&>::value);
+ }
+ SECTION("json_reverse_iterator")
+ {
+ using Base = nlohmann::detail::iter_impl<json>;
+ using Iter = nlohmann::detail::json_reverse_iterator<Base>;
+ CHECK_FALSE(is_detected<can_post_increment_temporary, Iter&>::value);
+ }
+ }
+ SECTION("post-decrement")
+ {
+ SECTION("primitive_iterator_t")
+ {
+ using Iter = nlohmann::detail::primitive_iterator_t;
+ CHECK_FALSE(is_detected<can_post_decrement_temporary, Iter&>::value);
+ }
+ SECTION("iter_impl")
+ {
+ using Iter = nlohmann::detail::iter_impl<json>;
+ CHECK_FALSE(is_detected<can_post_decrement_temporary, Iter&>::value);
+ }
+ SECTION("json_reverse_iterator")
+ {
+ using Base = nlohmann::detail::iter_impl<json>;
+ using Iter = nlohmann::detail::json_reverse_iterator<Base>;
+ CHECK_FALSE(is_detected<can_post_decrement_temporary, Iter&>::value);
+ }
+
+ }
+ }
+}