/src/solidity/deps/nlohmann-json/include/nlohmann/detail/hash.hpp
Line | Count | Source |
1 | | // __ _____ _____ _____ |
2 | | // __| | __| | | | JSON for Modern C++ |
3 | | // | | |__ | | | | | | version 3.12.0 |
4 | | // |_____|_____|_____|_|___| https://github.com/nlohmann/json |
5 | | // |
6 | | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me> |
7 | | // SPDX-License-Identifier: MIT |
8 | | |
9 | | #pragma once |
10 | | |
11 | | #include <cstdint> // uint8_t |
12 | | #include <cstddef> // size_t |
13 | | #include <functional> // hash |
14 | | |
15 | | #include <nlohmann/detail/abi_macros.hpp> |
16 | | #include <nlohmann/detail/value_t.hpp> |
17 | | |
18 | | NLOHMANN_JSON_NAMESPACE_BEGIN |
19 | | namespace detail |
20 | | { |
21 | | |
22 | | // boost::hash_combine |
23 | | inline std::size_t combine(std::size_t seed, std::size_t h) noexcept |
24 | 0 | { |
25 | 0 | seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); |
26 | 0 | return seed; |
27 | 0 | } |
28 | | |
29 | | /*! |
30 | | @brief hash a JSON value |
31 | | |
32 | | The hash function tries to rely on std::hash where possible. Furthermore, the |
33 | | type of the JSON value is taken into account to have different hash values for |
34 | | null, 0, 0U, and false, etc. |
35 | | |
36 | | @tparam BasicJsonType basic_json specialization |
37 | | @param j JSON value to hash |
38 | | @return hash value of j |
39 | | */ |
40 | | template<typename BasicJsonType> |
41 | | std::size_t hash(const BasicJsonType& j) |
42 | | { |
43 | | using string_t = typename BasicJsonType::string_t; |
44 | | using number_integer_t = typename BasicJsonType::number_integer_t; |
45 | | using number_unsigned_t = typename BasicJsonType::number_unsigned_t; |
46 | | using number_float_t = typename BasicJsonType::number_float_t; |
47 | | |
48 | | const auto type = static_cast<std::size_t>(j.type()); |
49 | | switch (j.type()) |
50 | | { |
51 | | case BasicJsonType::value_t::null: |
52 | | case BasicJsonType::value_t::discarded: |
53 | | { |
54 | | return combine(type, 0); |
55 | | } |
56 | | |
57 | | case BasicJsonType::value_t::object: |
58 | | { |
59 | | auto seed = combine(type, j.size()); |
60 | | for (const auto& element : j.items()) |
61 | | { |
62 | | const auto h = std::hash<string_t> {}(element.key()); |
63 | | seed = combine(seed, h); |
64 | | seed = combine(seed, hash(element.value())); |
65 | | } |
66 | | return seed; |
67 | | } |
68 | | |
69 | | case BasicJsonType::value_t::array: |
70 | | { |
71 | | auto seed = combine(type, j.size()); |
72 | | for (const auto& element : j) |
73 | | { |
74 | | seed = combine(seed, hash(element)); |
75 | | } |
76 | | return seed; |
77 | | } |
78 | | |
79 | | case BasicJsonType::value_t::string: |
80 | | { |
81 | | const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>()); |
82 | | return combine(type, h); |
83 | | } |
84 | | |
85 | | case BasicJsonType::value_t::boolean: |
86 | | { |
87 | | const auto h = std::hash<bool> {}(j.template get<bool>()); |
88 | | return combine(type, h); |
89 | | } |
90 | | |
91 | | case BasicJsonType::value_t::number_integer: |
92 | | { |
93 | | const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>()); |
94 | | return combine(type, h); |
95 | | } |
96 | | |
97 | | case BasicJsonType::value_t::number_unsigned: |
98 | | { |
99 | | const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>()); |
100 | | return combine(type, h); |
101 | | } |
102 | | |
103 | | case BasicJsonType::value_t::number_float: |
104 | | { |
105 | | const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>()); |
106 | | return combine(type, h); |
107 | | } |
108 | | |
109 | | case BasicJsonType::value_t::binary: |
110 | | { |
111 | | auto seed = combine(type, j.get_binary().size()); |
112 | | const auto h = std::hash<bool> {}(j.get_binary().has_subtype()); |
113 | | seed = combine(seed, h); |
114 | | seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype())); |
115 | | for (const auto byte : j.get_binary()) |
116 | | { |
117 | | seed = combine(seed, std::hash<std::uint8_t> {}(byte)); |
118 | | } |
119 | | return seed; |
120 | | } |
121 | | |
122 | | default: // LCOV_EXCL_LINE |
123 | | JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE |
124 | | return 0; // LCOV_EXCL_LINE |
125 | | } |
126 | | } |
127 | | |
128 | | } // namespace detail |
129 | | NLOHMANN_JSON_NAMESPACE_END |