💚 add test cases for hash
This commit is contained in:
		
							parent
							
								
									33b0bed7fe
								
							
						
					
					
						commit
						9449dfcc6a
					
				
					 5 changed files with 124 additions and 16 deletions
				
			
		|  | @ -8,7 +8,7 @@ namespace nlohmann | ||||||
| namespace detail | namespace detail | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| std::size_t combine(std::size_t seed, std::size_t h) | std::size_t combine(std::size_t seed, std::size_t h) noexcept | ||||||
| { | { | ||||||
|     seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); |     seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); | ||||||
|     return seed; |     return seed; | ||||||
|  | @ -17,6 +17,11 @@ std::size_t combine(std::size_t seed, std::size_t h) | ||||||
| template<typename BasicJsonType> | template<typename BasicJsonType> | ||||||
| std::size_t hash(const BasicJsonType& j) | std::size_t hash(const BasicJsonType& j) | ||||||
| { | { | ||||||
|  |     using string_t = typename BasicJsonType::string_t; | ||||||
|  |     using number_integer_t = typename BasicJsonType::number_integer_t; | ||||||
|  |     using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | ||||||
|  |     using number_float_t = typename BasicJsonType::number_float_t; | ||||||
|  | 
 | ||||||
|     switch (j.type()) |     switch (j.type()) | ||||||
|     { |     { | ||||||
|         case BasicJsonType::value_t::null: |         case BasicJsonType::value_t::null: | ||||||
|  | @ -28,7 +33,7 @@ std::size_t hash(const BasicJsonType& j) | ||||||
|             auto seed = combine(static_cast<std::size_t>(j.type()), j.size()); |             auto seed = combine(static_cast<std::size_t>(j.type()), j.size()); | ||||||
|             for (const auto& element : j.items()) |             for (const auto& element : j.items()) | ||||||
|             { |             { | ||||||
|                 const auto h = std::hash<typename BasicJsonType::string_t> {}(element.key()); |                 const auto h = std::hash<string_t> {}(element.key()); | ||||||
|                 seed = combine(seed, h); |                 seed = combine(seed, h); | ||||||
|                 seed = combine(seed, hash(element.value())); |                 seed = combine(seed, hash(element.value())); | ||||||
|             } |             } | ||||||
|  | @ -47,7 +52,7 @@ std::size_t hash(const BasicJsonType& j) | ||||||
| 
 | 
 | ||||||
|         case BasicJsonType::value_t::string: |         case BasicJsonType::value_t::string: | ||||||
|         { |         { | ||||||
|             const auto h = std::hash<typename BasicJsonType::string_t> {}(j.template get_ref<const typename BasicJsonType::string_t&>()); |             const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>()); | ||||||
|             return combine(static_cast<std::size_t>(j.type()), h); |             return combine(static_cast<std::size_t>(j.type()), h); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -59,25 +64,27 @@ std::size_t hash(const BasicJsonType& j) | ||||||
| 
 | 
 | ||||||
|         case BasicJsonType::value_t::number_integer: |         case BasicJsonType::value_t::number_integer: | ||||||
|         { |         { | ||||||
|             const auto h = std::hash<typename BasicJsonType::number_integer_t> {}(j.template get<typename BasicJsonType::number_integer_t>()); |             const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>()); | ||||||
|             return combine(static_cast<std::size_t>(j.type()), h); |             return combine(static_cast<std::size_t>(j.type()), h); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case nlohmann::detail::value_t::number_unsigned: |         case nlohmann::detail::value_t::number_unsigned: | ||||||
|         { |         { | ||||||
|             const auto h = std::hash<typename BasicJsonType::number_unsigned_t> {}(j.template get<typename BasicJsonType::number_unsigned_t>()); |             const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>()); | ||||||
|             return combine(static_cast<std::size_t>(j.type()), h); |             return combine(static_cast<std::size_t>(j.type()), h); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case nlohmann::detail::value_t::number_float: |         case nlohmann::detail::value_t::number_float: | ||||||
|         { |         { | ||||||
|             const auto h = std::hash<typename BasicJsonType::number_float_t> {}(j.template get<typename BasicJsonType::number_float_t>()); |             const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>()); | ||||||
|             return combine(static_cast<std::size_t>(j.type()), h); |             return combine(static_cast<std::size_t>(j.type()), h); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case nlohmann::detail::value_t::binary: |         case nlohmann::detail::value_t::binary: | ||||||
|         { |         { | ||||||
|             auto seed = combine(static_cast<std::size_t>(j.type()), j.get_binary().size()); |             auto seed = combine(static_cast<std::size_t>(j.type()), j.get_binary().size()); | ||||||
|  |             const auto h = std::hash<bool> {}(j.get_binary().has_subtype()); | ||||||
|  |             seed = combine(seed, h); | ||||||
|             seed = combine(seed, j.get_binary().subtype()); |             seed = combine(seed, j.get_binary().subtype()); | ||||||
|             for (const auto byte : j.get_binary()) |             for (const auto byte : j.get_binary()) | ||||||
|             { |             { | ||||||
|  | @ -85,9 +92,10 @@ std::size_t hash(const BasicJsonType& j) | ||||||
|             } |             } | ||||||
|             return seed; |             return seed; | ||||||
|         } |         } | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     return 0; |         default: // LCOV_EXCL_LINE
 | ||||||
|  |             JSON_ASSERT(false); // LCOV_EXCL_LINE
 | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| }  // namespace detail
 | }  // namespace detail
 | ||||||
|  |  | ||||||
|  | @ -4453,7 +4453,7 @@ namespace nlohmann | ||||||
| namespace detail | namespace detail | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| std::size_t combine(std::size_t seed, std::size_t h) | std::size_t combine(std::size_t seed, std::size_t h) noexcept | ||||||
| { | { | ||||||
|     seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); |     seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); | ||||||
|     return seed; |     return seed; | ||||||
|  | @ -4462,6 +4462,11 @@ std::size_t combine(std::size_t seed, std::size_t h) | ||||||
| template<typename BasicJsonType> | template<typename BasicJsonType> | ||||||
| std::size_t hash(const BasicJsonType& j) | std::size_t hash(const BasicJsonType& j) | ||||||
| { | { | ||||||
|  |     using string_t = typename BasicJsonType::string_t; | ||||||
|  |     using number_integer_t = typename BasicJsonType::number_integer_t; | ||||||
|  |     using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | ||||||
|  |     using number_float_t = typename BasicJsonType::number_float_t; | ||||||
|  | 
 | ||||||
|     switch (j.type()) |     switch (j.type()) | ||||||
|     { |     { | ||||||
|         case BasicJsonType::value_t::null: |         case BasicJsonType::value_t::null: | ||||||
|  | @ -4473,7 +4478,7 @@ std::size_t hash(const BasicJsonType& j) | ||||||
|             auto seed = combine(static_cast<std::size_t>(j.type()), j.size()); |             auto seed = combine(static_cast<std::size_t>(j.type()), j.size()); | ||||||
|             for (const auto& element : j.items()) |             for (const auto& element : j.items()) | ||||||
|             { |             { | ||||||
|                 const auto h = std::hash<typename BasicJsonType::string_t> {}(element.key()); |                 const auto h = std::hash<string_t> {}(element.key()); | ||||||
|                 seed = combine(seed, h); |                 seed = combine(seed, h); | ||||||
|                 seed = combine(seed, hash(element.value())); |                 seed = combine(seed, hash(element.value())); | ||||||
|             } |             } | ||||||
|  | @ -4492,7 +4497,7 @@ std::size_t hash(const BasicJsonType& j) | ||||||
| 
 | 
 | ||||||
|         case BasicJsonType::value_t::string: |         case BasicJsonType::value_t::string: | ||||||
|         { |         { | ||||||
|             const auto h = std::hash<typename BasicJsonType::string_t> {}(j.template get_ref<const typename BasicJsonType::string_t&>()); |             const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>()); | ||||||
|             return combine(static_cast<std::size_t>(j.type()), h); |             return combine(static_cast<std::size_t>(j.type()), h); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -4504,25 +4509,27 @@ std::size_t hash(const BasicJsonType& j) | ||||||
| 
 | 
 | ||||||
|         case BasicJsonType::value_t::number_integer: |         case BasicJsonType::value_t::number_integer: | ||||||
|         { |         { | ||||||
|             const auto h = std::hash<typename BasicJsonType::number_integer_t> {}(j.template get<typename BasicJsonType::number_integer_t>()); |             const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>()); | ||||||
|             return combine(static_cast<std::size_t>(j.type()), h); |             return combine(static_cast<std::size_t>(j.type()), h); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case nlohmann::detail::value_t::number_unsigned: |         case nlohmann::detail::value_t::number_unsigned: | ||||||
|         { |         { | ||||||
|             const auto h = std::hash<typename BasicJsonType::number_unsigned_t> {}(j.template get<typename BasicJsonType::number_unsigned_t>()); |             const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>()); | ||||||
|             return combine(static_cast<std::size_t>(j.type()), h); |             return combine(static_cast<std::size_t>(j.type()), h); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case nlohmann::detail::value_t::number_float: |         case nlohmann::detail::value_t::number_float: | ||||||
|         { |         { | ||||||
|             const auto h = std::hash<typename BasicJsonType::number_float_t> {}(j.template get<typename BasicJsonType::number_float_t>()); |             const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>()); | ||||||
|             return combine(static_cast<std::size_t>(j.type()), h); |             return combine(static_cast<std::size_t>(j.type()), h); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case nlohmann::detail::value_t::binary: |         case nlohmann::detail::value_t::binary: | ||||||
|         { |         { | ||||||
|             auto seed = combine(static_cast<std::size_t>(j.type()), j.get_binary().size()); |             auto seed = combine(static_cast<std::size_t>(j.type()), j.get_binary().size()); | ||||||
|  |             const auto h = std::hash<bool> {}(j.get_binary().has_subtype()); | ||||||
|  |             seed = combine(seed, h); | ||||||
|             seed = combine(seed, j.get_binary().subtype()); |             seed = combine(seed, j.get_binary().subtype()); | ||||||
|             for (const auto byte : j.get_binary()) |             for (const auto byte : j.get_binary()) | ||||||
|             { |             { | ||||||
|  | @ -4530,9 +4537,10 @@ std::size_t hash(const BasicJsonType& j) | ||||||
|             } |             } | ||||||
|             return seed; |             return seed; | ||||||
|         } |         } | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     return 0; |         default: // LCOV_EXCL_LINE
 | ||||||
|  |             JSON_ASSERT(false); // LCOV_EXCL_LINE
 | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| }  // namespace detail
 | }  // namespace detail
 | ||||||
|  |  | ||||||
|  | @ -112,6 +112,7 @@ set(files | ||||||
|     src/unit-deserialization.cpp |     src/unit-deserialization.cpp | ||||||
|     src/unit-element_access1.cpp |     src/unit-element_access1.cpp | ||||||
|     src/unit-element_access2.cpp |     src/unit-element_access2.cpp | ||||||
|  |     src/unit-hash.cpp | ||||||
|     src/unit-inspection.cpp |     src/unit-inspection.cpp | ||||||
|     src/unit-items.cpp |     src/unit-items.cpp | ||||||
|     src/unit-iterators1.cpp |     src/unit-iterators1.cpp | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ SOURCES = src/unit.cpp \ | ||||||
|           src/unit-algorithms.cpp \
 |           src/unit-algorithms.cpp \
 | ||||||
|           src/unit-allocator.cpp \
 |           src/unit-allocator.cpp \
 | ||||||
|           src/unit-alt-string.cpp \
 |           src/unit-alt-string.cpp \
 | ||||||
|  | 		  src/unit-assert_macro.cpp \
 | ||||||
|           src/unit-bson.cpp \
 |           src/unit-bson.cpp \
 | ||||||
|           src/unit-capacity.cpp \
 |           src/unit-capacity.cpp \
 | ||||||
|           src/unit-cbor.cpp \
 |           src/unit-cbor.cpp \
 | ||||||
|  |  | ||||||
							
								
								
									
										90
									
								
								test/src/unit-hash.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								test/src/unit-hash.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,90 @@ | ||||||
|  | /*
 | ||||||
|  |     __ _____ _____ _____ | ||||||
|  |  __|  |   __|     |   | |  JSON for Modern C++ (test suite) | ||||||
|  | |  |  |__   |  |  | | | |  version 3.8.0 | ||||||
|  | |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | ||||||
|  | 
 | ||||||
|  | Licensed under the MIT License <http://opensource.org/licenses/MIT>.
 | ||||||
|  | SPDX-License-Identifier: MIT | ||||||
|  | Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
 | ||||||
|  | 
 | ||||||
|  | Permission is hereby  granted, free of charge, to any  person obtaining a copy | ||||||
|  | of this software and associated  documentation files (the "Software"), to deal | ||||||
|  | in the Software  without restriction, including without  limitation the rights | ||||||
|  | to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell | ||||||
|  | copies  of  the Software,  and  to  permit persons  to  whom  the Software  is | ||||||
|  | furnished to do so, subject to the following conditions: | ||||||
|  | 
 | ||||||
|  | The above copyright notice and this permission notice shall be included in all | ||||||
|  | copies or substantial portions of the Software. | ||||||
|  | 
 | ||||||
|  | THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR | ||||||
|  | IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY, | ||||||
|  | FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE | ||||||
|  | AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER | ||||||
|  | LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  | OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  | SOFTWARE. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "doctest_compatibility.h" | ||||||
|  | 
 | ||||||
|  | #include <nlohmann/json.hpp> | ||||||
|  | using json = nlohmann::json; | ||||||
|  | 
 | ||||||
|  | TEST_CASE("hash") | ||||||
|  | { | ||||||
|  |     SECTION("null") | ||||||
|  |     { | ||||||
|  |         CHECK(std::hash<json> {}(json(nullptr)) == 2654435769U); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     SECTION("boolean") | ||||||
|  |     { | ||||||
|  |         CHECK(std::hash<json> {}(json(true)) == 2654436031U); | ||||||
|  |         CHECK(std::hash<json> {}(json(false)) == 2654436030U); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     SECTION("string") | ||||||
|  |     { | ||||||
|  |         CHECK(std::hash<json> {}(json("")) == 11160318156688833227U); | ||||||
|  |         CHECK(std::hash<json> {}(json("foo")) == 910203211069189493U); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     SECTION("number") | ||||||
|  |     { | ||||||
|  |         CHECK(std::hash<json> {}(json(int(0))) == 2654436095U); | ||||||
|  |         CHECK(std::hash<json> {}(json(unsigned(0))) == 2654436156U); | ||||||
|  | 
 | ||||||
|  |         CHECK(std::hash<json> {}(json(-1)) == 2654436092U); | ||||||
|  |         CHECK(std::hash<json> {}(json(0.0)) == 2654436221U); | ||||||
|  |         CHECK(std::hash<json> {}(json(42.23)) == 4631140164097181104U); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     SECTION("array") | ||||||
|  |     { | ||||||
|  |         CHECK(std::hash<json> {}(json::array()) == 2654435899U); | ||||||
|  |         CHECK(std::hash<json> {}(json::array({1, 2, 3})) == 717272658337467U); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     SECTION("object") | ||||||
|  |     { | ||||||
|  |         CHECK(std::hash<json> {}(json::object()) == 2654435832U); | ||||||
|  |         CHECK(std::hash<json> {}(json::object({{"foo", "bar"}})) == 4042265434648078139U); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     SECTION("binary") | ||||||
|  |     { | ||||||
|  |         CHECK(std::hash<json> {}(json::binary({})) == 11093832941624U); | ||||||
|  |         CHECK(std::hash<json> {}(json::binary({}, 0)) == 11093832941691U); | ||||||
|  |         CHECK(std::hash<json> {}(json::binary({}, 42)) == 11093832941581U); | ||||||
|  |         CHECK(std::hash<json> {}(json::binary({1, 2, 3})) == 3005324138949694928U); | ||||||
|  |         CHECK(std::hash<json> {}(json::binary({1, 2, 3}, 0)) == 3005324138988516582U); | ||||||
|  |         CHECK(std::hash<json> {}(json::binary({1, 2, 3}, 42)) == 3005324138986241627U); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     SECTION("discarded") | ||||||
|  |     { | ||||||
|  |         CHECK(std::hash<json> {}(json(json::value_t::discarded)) == 2654436338U); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue