It was a good idea to implement a const version of operator[] it in the first place. I was a pity that this implementation was flawed. It was a mistake to remove the const version completely. This commit re-introduces the const version. My apologies for all the inconvenience.
This commit is contained in:
		
							parent
							
								
									9def0186be
								
							
						
					
					
						commit
						4351698c83
					
				
					 5 changed files with 197 additions and 2 deletions
				
			
		|  | @ -5,7 +5,7 @@ using namespace nlohmann; | |||
| int main() | ||||
| { | ||||
|     // create a JSON object
 | ||||
|     json object = | ||||
|     const json object = | ||||
|     { | ||||
|         {"one", 1}, {"two", 2}, {"three", 2.9} | ||||
|     }; | ||||
|  |  | |||
|  | @ -1 +1 @@ | |||
| <a target="_blank" href="http://melpon.org/wandbox/permlink/9X5Q8p7DlWA6v0Ey"><b>online</b></a> | ||||
| <a target="_blank" href="http://melpon.org/wandbox/permlink/4WLxv7id8P64Q1KI"><b>online</b></a> | ||||
							
								
								
									
										81
									
								
								src/json.hpp
									
										
									
									
									
								
							
							
						
						
									
										81
									
								
								src/json.hpp
									
										
									
									
									
								
							|  | @ -2862,6 +2862,45 @@ class basic_json | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief read-only access specified object element | ||||
| 
 | ||||
|     Returns a const reference to the element at with specified key @a key. No | ||||
|     bounds checking is performed. | ||||
| 
 | ||||
|     @warning If the element with key @a key does not exist, the behavior is | ||||
|     undefined. | ||||
| 
 | ||||
|     @param[in] key  key of the element to access | ||||
| 
 | ||||
|     @return const reference to the element at key @a key | ||||
| 
 | ||||
|     @throw std::domain_error if JSON is not an object | ||||
| 
 | ||||
|     @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} | ||||
| 
 | ||||
|     @sa @ref at(const typename object_t::key_type&) for access by reference | ||||
|     with range checking | ||||
|     @sa @ref value() for access by value with a default value | ||||
| 
 | ||||
|     @since version 1.0 | ||||
|     */ | ||||
|     const_reference operator[](const typename object_t::key_type& key) const | ||||
|     { | ||||
|         // [] only works for objects
 | ||||
|         if (is_object()) | ||||
|         { | ||||
|             return m_value.object->find(key)->second; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             throw std::domain_error("cannot use operator[] with " + type_name()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief access specified object element | ||||
| 
 | ||||
|  | @ -2911,6 +2950,48 @@ class basic_json | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief read-only access specified object element | ||||
| 
 | ||||
|     Returns a const reference to the element at with specified key @a key. No | ||||
|     bounds checking is performed. | ||||
| 
 | ||||
|     @warning If the element with key @a key does not exist, the behavior is | ||||
|     undefined. | ||||
| 
 | ||||
|     @note This function is required for compatibility reasons with Clang. | ||||
| 
 | ||||
|     @param[in] key  key of the element to access | ||||
| 
 | ||||
|     @return const reference to the element at key @a key | ||||
| 
 | ||||
|     @throw std::domain_error if JSON is not an object | ||||
| 
 | ||||
|     @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} | ||||
| 
 | ||||
|     @sa @ref at(const typename object_t::key_type&) for access by reference | ||||
|     with range checking | ||||
|     @sa @ref value() for access by value with a default value | ||||
| 
 | ||||
|     @since version 1.0 | ||||
|     */ | ||||
|     template<typename T, std::size_t n> | ||||
|     const_reference operator[](const T (&key)[n]) const | ||||
|     { | ||||
|         // at only works for objects
 | ||||
|         if (is_object()) | ||||
|         { | ||||
|             return m_value.object->find(key)->second; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             throw std::domain_error("cannot use operator[] with " + type_name()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief access specified object element with default value | ||||
| 
 | ||||
|  |  | |||
|  | @ -2862,6 +2862,45 @@ class basic_json | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*! | ||||
|     @brief read-only access specified object element | ||||
| 
 | ||||
|     Returns a const reference to the element at with specified key @a key. No | ||||
|     bounds checking is performed. | ||||
| 
 | ||||
|     @warning If the element with key @a key does not exist, the behavior is | ||||
|     undefined. | ||||
| 
 | ||||
|     @param[in] key  key of the element to access | ||||
| 
 | ||||
|     @return const reference to the element at key @a key | ||||
| 
 | ||||
|     @throw std::domain_error if JSON is not an object | ||||
| 
 | ||||
|     @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} | ||||
| 
 | ||||
|     @sa @ref at(const typename object_t::key_type&) for access by reference | ||||
|     with range checking | ||||
|     @sa @ref value() for access by value with a default value | ||||
| 
 | ||||
|     @since version 1.0 | ||||
|     */ | ||||
|     const_reference operator[](const typename object_t::key_type& key) const | ||||
|     { | ||||
|         // [] only works for objects | ||||
|         if (is_object()) | ||||
|         { | ||||
|             return m_value.object->find(key)->second; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             throw std::domain_error("cannot use operator[] with " + type_name()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*! | ||||
|     @brief access specified object element | ||||
| 
 | ||||
|  | @ -2911,6 +2950,48 @@ class basic_json | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*! | ||||
|     @brief read-only access specified object element | ||||
| 
 | ||||
|     Returns a const reference to the element at with specified key @a key. No | ||||
|     bounds checking is performed. | ||||
| 
 | ||||
|     @warning If the element with key @a key does not exist, the behavior is | ||||
|     undefined. | ||||
| 
 | ||||
|     @note This function is required for compatibility reasons with Clang. | ||||
| 
 | ||||
|     @param[in] key  key of the element to access | ||||
| 
 | ||||
|     @return const reference to the element at key @a key | ||||
| 
 | ||||
|     @throw std::domain_error if JSON is not an object | ||||
| 
 | ||||
|     @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} | ||||
| 
 | ||||
|     @sa @ref at(const typename object_t::key_type&) for access by reference | ||||
|     with range checking | ||||
|     @sa @ref value() for access by value with a default value | ||||
| 
 | ||||
|     @since version 1.0 | ||||
|     */ | ||||
|     template<typename T, std::size_t n> | ||||
|     const_reference operator[](const T (&key)[n]) const | ||||
|     { | ||||
|         // at only works for objects | ||||
|         if (is_object()) | ||||
|         { | ||||
|             return m_value.object->find(key)->second; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             throw std::domain_error("cannot use operator[] with " + type_name()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*! | ||||
|     @brief access specified object element with default value | ||||
| 
 | ||||
|  |  | |||
|  | @ -3211,6 +3211,27 @@ TEST_CASE("element access") | |||
| 
 | ||||
|                 CHECK(j["array"] == json({1, 2, 3})); | ||||
|                 CHECK(j[json::object_t::key_type("array")] == j["array"]); | ||||
| 
 | ||||
|                 CHECK(j_const["integer"] == json(1)); | ||||
|                 CHECK(j_const[json::object_t::key_type("integer")] == j["integer"]); | ||||
| 
 | ||||
|                 CHECK(j_const["boolean"] == json(true)); | ||||
|                 CHECK(j_const[json::object_t::key_type("boolean")] == j["boolean"]); | ||||
| 
 | ||||
|                 CHECK(j_const["null"] == json(nullptr)); | ||||
|                 CHECK(j_const[json::object_t::key_type("null")] == j["null"]); | ||||
| 
 | ||||
|                 CHECK(j_const["string"] == json("hello world")); | ||||
|                 CHECK(j_const[json::object_t::key_type("string")] == j["string"]); | ||||
| 
 | ||||
|                 CHECK(j_const["floating"] == json(42.23)); | ||||
|                 CHECK(j_const[json::object_t::key_type("floating")] == j["floating"]); | ||||
| 
 | ||||
|                 CHECK(j_const["object"] == json(json::object())); | ||||
|                 CHECK(j_const[json::object_t::key_type("object")] == j["object"]); | ||||
| 
 | ||||
|                 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") | ||||
|  | @ -3222,6 +3243,8 @@ 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") | ||||
|  | @ -3230,6 +3253,8 @@ 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") | ||||
|  | @ -3238,6 +3263,8 @@ 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") | ||||
|  | @ -3246,6 +3273,8 @@ 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)") | ||||
|  | @ -3254,6 +3283,8 @@ 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)") | ||||
|  | @ -3262,6 +3293,8 @@ 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); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue