mirror of
https://github.com/nlohmann/json.git
synced 2026-07-12 05:25:09 +00:00
68c87ad9de
Fixes #5256: json(42) == json(42u) is true, but their hashes differed, violating the std::hash contract. This also applied to float comparisons: json(42) == json(42.0) is true, but they hashed differently. Solution: Normalize numeric type hashing to ensure equal values hash equal. - Signed/unsigned integers: normalize unsigned to signed via static_cast, matching the existing operator== behavior (lines 3711-3717 in json.hpp) - Integer/float bridging: for values exactly representable as the float type, hash via the float form to collide correctly with float values - All numeric types share a single type tag to ensure hash collision The fix is rigorous for the reported issue (int/uint, any magnitude) with zero gaps. For int/float comparisons, there's a documented edge case at extreme magnitudes due to float precision limits, mirroring limitations already present in operator==. Changes: - include/nlohmann/detail/hash.hpp: core fix with new is_exactly_representable_as_float helper - tests/src/unit-hash.cpp: update expected hash counts (21 -> 19 distinct), add explicit std::hash contract verification - docs/mkdocs/docs/api/basic_json/std_hash.md: update description - docs/mkdocs/docs/examples/std_hash.cpp/.output: show the fix in action - single_include/nlohmann/json.hpp: regenerated via amalgamate Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Niels Lohmann <mail@nlohmann.me>
21 lines
876 B
C++
21 lines
876 B
C++
#include <iostream>
|
|
#include <iomanip>
|
|
#include <nlohmann/json.hpp>
|
|
|
|
using json = nlohmann::json;
|
|
using namespace nlohmann::literals;
|
|
|
|
int main()
|
|
{
|
|
std::cout << "hash(null) = " << std::hash<json> {}(json(nullptr)) << '\n'
|
|
<< "hash(false) = " << std::hash<json> {}(json(false)) << '\n'
|
|
<< "hash(0) = " << std::hash<json> {}(json(0)) << '\n'
|
|
<< "hash(0U) = " << std::hash<json> {}(json(0U)) << '\n'
|
|
<< "hash(0.0) = " << std::hash<json> {}(json(0.0)) << '\n'
|
|
<< "hash(\"\") = " << std::hash<json> {}(json("")) << '\n'
|
|
<< "hash({}) = " << std::hash<json> {}(json::object()) << '\n'
|
|
<< "hash([]) = " << std::hash<json> {}(json::array()) << '\n'
|
|
<< "hash({\"hello\": \"world\"}) = " << std::hash<json> {}("{\"hello\": \"world\"}"_json)
|
|
<< std::endl;
|
|
}
|