diff --git a/Makefile b/Makefile index 4353eb30..105f4369 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ RE2C = re2c SED = gsed # additional flags -FLAGS = -Wall -Wextra -pedantic -Weffc++ -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-overflow=5 -Wswitch -Wundef -Wno-unused -Wnon-virtual-dtor -Wreorder +FLAGS = -Wall -Wextra -pedantic -Weffc++ -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-overflow=5 -Wswitch -Wundef -Wno-unused -Wnon-virtual-dtor -Wreorder -Wdeprecated all: json_unit diff --git a/src/json.hpp b/src/json.hpp index 89269ea3..09880b9e 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -1049,7 +1049,6 @@ class basic_json return m_value.object->operator[](key); } - /// find an element in an object inline iterator find(typename object_t::key_type key) { @@ -1076,6 +1075,13 @@ class basic_json return result; } + /// returns the number of occurrences of a key in an object + inline size_type count(typename object_t::key_type key) const + { + // return 0 for all nonobject types + return (m_type == value_t::object) ? m_value.object->count(key) : 0; + } + /////////////// // iterators // diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 5ebda5a7..36bb0e00 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -1049,7 +1049,6 @@ class basic_json return m_value.object->operator[](key); } - /// find an element in an object inline iterator find(typename object_t::key_type key) { @@ -1076,6 +1075,13 @@ class basic_json return result; } + /// returns the number of occurrences of a key in an object + inline size_type count(typename object_t::key_type key) const + { + // return 0 for all nonobject types + return (m_type == value_t::object) ? m_value.object->count(key) : 0; + } + /////////////// // iterators // diff --git a/test/unit.cpp b/test/unit.cpp index 81bfa977..fb73205a 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -2441,6 +2441,85 @@ TEST_CASE("element access") } } } + + SECTION("count keys in an object") + { + SECTION("existing element") + { + for (auto key : + {"integer", "floating", "null", "string", "boolean", "object", "array" + }) + { + CHECK(j.count(key) == 1); + CHECK(j_const.count(key) == 1); + } + } + + SECTION("nonexisting element") + { + CHECK(j.count("foo") == 0); + CHECK(j_const.count("foo") == 0); + } + + SECTION("all types") + { + SECTION("null") + { + json j_nonobject(json::value_t::null); + const json j_nonobject_const(j_nonobject); + CHECK(j_nonobject.count("foo") == 0); + CHECK(j_nonobject_const.count("foo") == 0); + } + + SECTION("string") + { + json j_nonobject(json::value_t::string); + const json j_nonobject_const(j_nonobject); + CHECK(j_nonobject.count("foo") == 0); + CHECK(j_nonobject_const.count("foo") == 0); + } + + SECTION("object") + { + json j_nonobject(json::value_t::object); + const json j_nonobject_const(j_nonobject); + CHECK(j_nonobject.count("foo") == 0); + CHECK(j_nonobject_const.count("foo") == 0); + } + + SECTION("array") + { + json j_nonobject(json::value_t::array); + const json j_nonobject_const(j_nonobject); + CHECK(j_nonobject.count("foo") == 0); + CHECK(j_nonobject_const.count("foo") == 0); + } + + SECTION("boolean") + { + json j_nonobject(json::value_t::boolean); + const json j_nonobject_const(j_nonobject); + CHECK(j_nonobject.count("foo") == 0); + CHECK(j_nonobject_const.count("foo") == 0); + } + + SECTION("number (integer)") + { + json j_nonobject(json::value_t::number_integer); + const json j_nonobject_const(j_nonobject); + CHECK(j_nonobject.count("foo") == 0); + CHECK(j_nonobject_const.count("foo") == 0); + } + + SECTION("number (floating-point)") + { + json j_nonobject(json::value_t::number_float); + const json j_nonobject_const(j_nonobject); + CHECK(j_nonobject.count("foo") == 0); + CHECK(j_nonobject_const.count("foo") == 0); + } + } + } } }