fixed #135: operator[] now only works on nonconst JSON objects
This commit is contained in:
parent
c767f464bb
commit
a70a7a8001
4 changed files with 3 additions and 145 deletions
|
@ -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:
|
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
|
- GCC 4.9 - 5.2 (and possible later)
|
||||||
- Clang 3.4 - 3.7
|
- Clang 3.4 - 3.7 (and possible later)
|
||||||
- Microsoft Visual C++ 14.0 RC
|
- Microsoft Visual C++ 14.0 RC (and possible later)
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
I would be happy to learn about other compilers/versions.
|
I would be happy to learn about other compilers/versions.
|
||||||
|
|
||||||
|
|
57
src/json.hpp
57
src/json.hpp
|
@ -2691,33 +2691,6 @@ class basic_json
|
||||||
|
|
||||||
Returns a reference to the element at with specified key @a key.
|
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
|
@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.
|
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.
|
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);
|
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<typename T, std::size_t n>
|
|
||||||
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
|
@brief access the first element
|
||||||
|
|
||||||
|
|
|
@ -2691,33 +2691,6 @@ class basic_json
|
||||||
|
|
||||||
Returns a reference to the element at with specified key @a key.
|
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
|
@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.
|
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.
|
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);
|
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<typename T, std::size_t n>
|
|
||||||
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
|
@brief access the first element
|
||||||
|
|
||||||
|
|
|
@ -3098,38 +3098,24 @@ TEST_CASE("element access")
|
||||||
{
|
{
|
||||||
CHECK(j["integer"] == json(1));
|
CHECK(j["integer"] == json(1));
|
||||||
CHECK(j[json::object_t::key_type("integer")] == j["integer"]);
|
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["boolean"] == json(true));
|
||||||
CHECK(j[json::object_t::key_type("boolean")] == j["boolean"]);
|
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["null"] == json(nullptr));
|
||||||
CHECK(j[json::object_t::key_type("null")] == j["null"]);
|
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["string"] == json("hello world"));
|
||||||
CHECK(j[json::object_t::key_type("string")] == j["string"]);
|
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["floating"] == json(42.23));
|
||||||
CHECK(j[json::object_t::key_type("floating")] == j["floating"]);
|
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["object"] == json(json::object()));
|
||||||
CHECK(j[json::object_t::key_type("object")] == j["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["array"] == json({1, 2, 3}));
|
||||||
CHECK(j[json::object_t::key_type("array")] == j["array"]);
|
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")
|
SECTION("access on non-object type")
|
||||||
|
@ -3141,8 +3127,6 @@ TEST_CASE("element access")
|
||||||
const json j_const_nonobject(j_nonobject);
|
const json j_const_nonobject(j_nonobject);
|
||||||
CHECK_NOTHROW(j_nonobject["foo"]);
|
CHECK_NOTHROW(j_nonobject["foo"]);
|
||||||
CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("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")
|
SECTION("boolean")
|
||||||
|
@ -3151,8 +3135,6 @@ TEST_CASE("element access")
|
||||||
const json j_const_nonobject(j_nonobject);
|
const json j_const_nonobject(j_nonobject);
|
||||||
CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error);
|
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_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")
|
SECTION("string")
|
||||||
|
@ -3161,8 +3143,6 @@ TEST_CASE("element access")
|
||||||
const json j_const_nonobject(j_nonobject);
|
const json j_const_nonobject(j_nonobject);
|
||||||
CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error);
|
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_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")
|
SECTION("array")
|
||||||
|
@ -3171,8 +3151,6 @@ TEST_CASE("element access")
|
||||||
const json j_const_nonobject(j_nonobject);
|
const json j_const_nonobject(j_nonobject);
|
||||||
CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error);
|
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_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)")
|
SECTION("number (integer)")
|
||||||
|
@ -3181,8 +3159,6 @@ TEST_CASE("element access")
|
||||||
const json j_const_nonobject(j_nonobject);
|
const json j_const_nonobject(j_nonobject);
|
||||||
CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error);
|
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_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)")
|
SECTION("number (floating-point)")
|
||||||
|
@ -3191,8 +3167,6 @@ TEST_CASE("element access")
|
||||||
const json j_const_nonobject(j_nonobject);
|
const json j_const_nonobject(j_nonobject);
|
||||||
CHECK_THROWS_AS(j_nonobject["foo"], std::domain_error);
|
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_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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue