From a70a7a8001f4d5e1d0ac2b652ba5c1ba04a4b648 Mon Sep 17 00:00:00 2001 From: Niels Date: Sun, 13 Dec 2015 11:26:55 +0100 Subject: [PATCH] fixed #135: operator[] now only works on nonconst JSON objects --- README.md | 8 +++---- src/json.hpp | 57 ----------------------------------------------- src/json.hpp.re2c | 57 ----------------------------------------------- test/unit.cpp | 26 --------------------- 4 files changed, 3 insertions(+), 145 deletions(-) diff --git a/README.md b/README.md index 827dd2575..a4093fa2a 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,9 @@ to the files you want to use JSON objects. That's it. Do not forget to set the n Though it's 2015 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work: -- GCC 4.9 - 5.2 -- Clang 3.4 - 3.7 -- Microsoft Visual C++ 14.0 RC - -Note using GCC 4.8, the unit tests cannot be compiled due to a [bug in the preprocessor](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55971). +- GCC 4.9 - 5.2 (and possible later) +- Clang 3.4 - 3.7 (and possible later) +- Microsoft Visual C++ 14.0 RC (and possible later) I would be happy to learn about other compilers/versions. diff --git a/src/json.hpp b/src/json.hpp index 236499753..a2053ad04 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -2691,33 +2691,6 @@ class basic_json Returns a reference to the element at with specified key @a key. - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw std::domain_error if JSON is not an object or null - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the [] operator.,operatorarray__key_type_const} - */ - const_reference operator[](const typename object_t::key_type& key) const - { - // at only works for objects - if (m_type != value_t::object) - { - throw std::domain_error("cannot use operator[] with " + type_name()); - } - - return m_value.object->operator[](key); - } - - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - @note If @a key is not found in the object, then it is silently added to the object and filled with a `null` value to make `key` a valid reference. In case the value was `null` before, it is converted to an object. @@ -2754,36 +2727,6 @@ class basic_json return m_value.object->operator[](key); } - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - - @note This function is required for compatibility reasons with Clang. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw std::domain_error if JSON is not an object or null - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the [] operator.,operatorarray__key_type_const} - */ - template - const_reference operator[](const T (&key)[n]) const - { - // at only works for objects - if (m_type != value_t::object) - { - throw std::domain_error("cannot use operator[] with " + type_name()); - } - - return m_value.object->operator[](key); - } - /*! @brief access the first element diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index da03e0fa3..4f056f34a 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -2691,33 +2691,6 @@ class basic_json Returns a reference to the element at with specified key @a key. - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw std::domain_error if JSON is not an object or null - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the [] operator.,operatorarray__key_type_const} - */ - const_reference operator[](const typename object_t::key_type& key) const - { - // at only works for objects - if (m_type != value_t::object) - { - throw std::domain_error("cannot use operator[] with " + type_name()); - } - - return m_value.object->operator[](key); - } - - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - @note If @a key is not found in the object, then it is silently added to the object and filled with a `null` value to make `key` a valid reference. In case the value was `null` before, it is converted to an object. @@ -2754,36 +2727,6 @@ class basic_json return m_value.object->operator[](key); } - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - - @note This function is required for compatibility reasons with Clang. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw std::domain_error if JSON is not an object or null - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the [] operator.,operatorarray__key_type_const} - */ - template - const_reference operator[](const T (&key)[n]) const - { - // at only works for objects - if (m_type != value_t::object) - { - throw std::domain_error("cannot use operator[] with " + type_name()); - } - - return m_value.object->operator[](key); - } - /*! @brief access the first element diff --git a/test/unit.cpp b/test/unit.cpp index 56287764d..efc71ff5f 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -3098,38 +3098,24 @@ TEST_CASE("element access") { CHECK(j["integer"] == json(1)); CHECK(j[json::object_t::key_type("integer")] == j["integer"]); - CHECK(j_const["integer"] == json(1)); - CHECK(j_const[json::object_t::key_type("integer")] == j["integer"]); CHECK(j["boolean"] == json(true)); CHECK(j[json::object_t::key_type("boolean")] == j["boolean"]); - CHECK(j_const["boolean"] == json(true)); - CHECK(j_const[json::object_t::key_type("boolean")] == j["boolean"]); CHECK(j["null"] == json(nullptr)); CHECK(j[json::object_t::key_type("null")] == j["null"]); - CHECK(j_const["null"] == json(nullptr)); - CHECK(j_const[json::object_t::key_type("null")] == j["null"]); CHECK(j["string"] == json("hello world")); CHECK(j[json::object_t::key_type("string")] == j["string"]); - CHECK(j_const["string"] == json("hello world")); - CHECK(j_const[json::object_t::key_type("string")] == j["string"]); CHECK(j["floating"] == json(42.23)); CHECK(j[json::object_t::key_type("floating")] == j["floating"]); - CHECK(j_const["floating"] == json(42.23)); - CHECK(j_const[json::object_t::key_type("floating")] == j["floating"]); CHECK(j["object"] == json(json::object())); CHECK(j[json::object_t::key_type("object")] == j["object"]); - CHECK(j_const["object"] == json(json::object())); - CHECK(j_const[json::object_t::key_type("object")] == j["object"]); CHECK(j["array"] == json({1, 2, 3})); CHECK(j[json::object_t::key_type("array")] == j["array"]); - CHECK(j_const["array"] == json({1, 2, 3})); - CHECK(j_const[json::object_t::key_type("array")] == j["array"]); } SECTION("access on non-object type") @@ -3141,8 +3127,6 @@ TEST_CASE("element access") const json j_const_nonobject(j_nonobject); CHECK_NOTHROW(j_nonobject["foo"]); CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("foo")]); - CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); - CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); } SECTION("boolean") @@ -3151,8 +3135,6 @@ TEST_CASE("element access") const json j_const_nonobject(j_nonobject); CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); - CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); - CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); } SECTION("string") @@ -3161,8 +3143,6 @@ TEST_CASE("element access") const json j_const_nonobject(j_nonobject); CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); - CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); - CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); } SECTION("array") @@ -3171,8 +3151,6 @@ TEST_CASE("element access") const json j_const_nonobject(j_nonobject); CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); - CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); - CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); } SECTION("number (integer)") @@ -3181,8 +3159,6 @@ TEST_CASE("element access") const json j_const_nonobject(j_nonobject); CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); - CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); - CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); } SECTION("number (floating-point)") @@ -3191,8 +3167,6 @@ TEST_CASE("element access") const json j_const_nonobject(j_nonobject); CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); - CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); - CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); } } }