From 47ea1c10d4eb23367fe6065983f45889f40bb56d Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 24 Mar 2015 19:08:03 +0100 Subject: [PATCH] key/value function for iterators (#46) Currently only support iterator and const_iterator. reverse_iterator and const_reverse_iterator to be implemented soon. --- src/json.hpp | 46 +++++++++++++++++++++++++++++++ src/json.hpp.re2c | 46 +++++++++++++++++++++++++++++++ test/unit.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+) diff --git a/src/json.hpp b/src/json.hpp index 064871ef..bad8f7ee 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -2137,6 +2137,7 @@ class basic_json return *this; } + private: /// set the iterator to the first value inline void set_begin() noexcept { @@ -2194,6 +2195,7 @@ class basic_json } } + public: /// return a reference to the value pointed to by the iterator inline reference operator*() { @@ -2559,6 +2561,27 @@ class basic_json } } + inline typename object_t::key_type key() const + { + switch (m_object->m_type) + { + case (basic_json::value_t::object): + { + return m_it.object_iterator->first; + } + + default: + { + throw std::domain_error("cannot use key() for non-object iterators"); + } + } + } + + inline reference value() + { + return operator*(); + } + private: /// associated JSON instance pointer m_object = nullptr; @@ -2654,6 +2677,7 @@ class basic_json return *this; } + private: /// set the iterator to the first value inline void set_begin() noexcept { @@ -2711,6 +2735,7 @@ class basic_json } } + public: /// return a reference to the value pointed to by the iterator inline reference operator*() const { @@ -3071,6 +3096,27 @@ class basic_json } } + inline typename object_t::key_type key() const + { + switch (m_object->m_type) + { + case (basic_json::value_t::object): + { + return m_it.object_iterator->first; + } + + default: + { + throw std::domain_error("cannot use key() for non-object iterators"); + } + } + } + + inline reference value() const + { + return operator*(); + } + private: /// associated JSON instance pointer m_object = nullptr; diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index ebf84b89..df00587d 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -2137,6 +2137,7 @@ class basic_json return *this; } + private: /// set the iterator to the first value inline void set_begin() noexcept { @@ -2194,6 +2195,7 @@ class basic_json } } + public: /// return a reference to the value pointed to by the iterator inline reference operator*() { @@ -2559,6 +2561,27 @@ class basic_json } } + inline typename object_t::key_type key() const + { + switch (m_object->m_type) + { + case (basic_json::value_t::object): + { + return m_it.object_iterator->first; + } + + default: + { + throw std::domain_error("cannot use key() for non-object iterators"); + } + } + } + + inline reference value() + { + return operator*(); + } + private: /// associated JSON instance pointer m_object = nullptr; @@ -2654,6 +2677,7 @@ class basic_json return *this; } + private: /// set the iterator to the first value inline void set_begin() noexcept { @@ -2711,6 +2735,7 @@ class basic_json } } + public: /// return a reference to the value pointed to by the iterator inline reference operator*() const { @@ -3071,6 +3096,27 @@ class basic_json } } + inline typename object_t::key_type key() const + { + switch (m_object->m_type) + { + case (basic_json::value_t::object): + { + return m_it.object_iterator->first; + } + + default: + { + throw std::domain_error("cannot use key() for non-object iterators"); + } + } + } + + inline reference value() const + { + return operator*(); + } + private: /// associated JSON instance pointer m_object = nullptr; diff --git a/test/unit.cpp b/test/unit.cpp index 066af8b6..b5bdac60 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -2801,6 +2801,16 @@ TEST_CASE("iterators") CHECK(it != j_const.crend()); CHECK(*it == j_const); } + + SECTION("key/value") + { + auto it = j.begin(); + auto cit = j_const.cbegin(); + CHECK_THROWS_AS(it.key(), std::domain_error); + CHECK(it.value() == json(true)); + CHECK_THROWS_AS(cit.key(), std::domain_error); + CHECK(cit.value() == json(true)); + } } SECTION("string") @@ -2982,6 +2992,16 @@ TEST_CASE("iterators") CHECK(it != j_const.crend()); CHECK(*it == j_const); } + + SECTION("key/value") + { + auto it = j.begin(); + auto cit = j_const.cbegin(); + CHECK_THROWS_AS(it.key(), std::domain_error); + CHECK(it.value() == json("hello world")); + CHECK_THROWS_AS(cit.key(), std::domain_error); + CHECK(cit.value() == json("hello world")); + } } SECTION("array") @@ -3156,6 +3176,16 @@ TEST_CASE("iterators") CHECK(it != it_begin); CHECK(it == it_end); } + + SECTION("key/value") + { + auto it = j.begin(); + auto cit = j_const.cbegin(); + CHECK_THROWS_AS(it.key(), std::domain_error); + CHECK(it.value() == json(1)); + CHECK_THROWS_AS(cit.key(), std::domain_error); + CHECK(cit.value() == json(1)); + } } SECTION("object") @@ -3330,6 +3360,16 @@ TEST_CASE("iterators") CHECK(it != it_begin); CHECK(it == it_end); } + + SECTION("key/value") + { + auto it = j.begin(); + auto cit = j_const.cbegin(); + CHECK(it.key() == "A"); + CHECK(it.value() == json(1)); + CHECK(cit.key() == "A"); + CHECK(cit.value() == json(1)); + } } SECTION("number (integer)") @@ -3511,6 +3551,16 @@ TEST_CASE("iterators") CHECK(it != j_const.crend()); CHECK(*it == j_const); } + + SECTION("key/value") + { + auto it = j.begin(); + auto cit = j_const.cbegin(); + CHECK_THROWS_AS(it.key(), std::domain_error); + CHECK(it.value() == json(23)); + CHECK_THROWS_AS(cit.key(), std::domain_error); + CHECK(cit.value() == json(23)); + } } SECTION("number (float)") @@ -3692,6 +3742,16 @@ TEST_CASE("iterators") CHECK(it != j_const.crend()); CHECK(*it == j_const); } + + SECTION("key/value") + { + auto it = j.begin(); + auto cit = j_const.cbegin(); + CHECK_THROWS_AS(it.key(), std::domain_error); + CHECK(it.value() == json(23.42)); + CHECK_THROWS_AS(cit.key(), std::domain_error); + CHECK(cit.value() == json(23.42)); + } } SECTION("null") @@ -3743,6 +3803,16 @@ TEST_CASE("iterators") json::const_reverse_iterator it = j_const.crbegin(); CHECK(it == j_const.crend()); } + + SECTION("key/value") + { + auto it = j.begin(); + auto cit = j_const.cbegin(); + CHECK_THROWS_AS(it.key(), std::domain_error); + CHECK_THROWS_AS(it.value(), std::out_of_range); + CHECK_THROWS_AS(cit.key(), std::domain_error); + CHECK_THROWS_AS(cit.value(), std::out_of_range); + } } }