File indexing completed on 2024-11-15 09:44:46
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <cstdint> // uint8_t
0012 #include <cstddef> // size_t
0013 #include <functional> // hash
0014
0015 #include <nlohmann/detail/abi_macros.hpp>
0016 #include <nlohmann/detail/value_t.hpp>
0017
0018 NLOHMANN_JSON_NAMESPACE_BEGIN
0019 namespace detail
0020 {
0021
0022
0023 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
0024 {
0025 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
0026 return seed;
0027 }
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 template<typename BasicJsonType>
0041 std::size_t hash(const BasicJsonType& j)
0042 {
0043 using string_t = typename BasicJsonType::string_t;
0044 using number_integer_t = typename BasicJsonType::number_integer_t;
0045 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
0046 using number_float_t = typename BasicJsonType::number_float_t;
0047
0048 const auto type = static_cast<std::size_t>(j.type());
0049 switch (j.type())
0050 {
0051 case BasicJsonType::value_t::null:
0052 case BasicJsonType::value_t::discarded:
0053 {
0054 return combine(type, 0);
0055 }
0056
0057 case BasicJsonType::value_t::object:
0058 {
0059 auto seed = combine(type, j.size());
0060 for (const auto& element : j.items())
0061 {
0062 const auto h = std::hash<string_t> {}(element.key());
0063 seed = combine(seed, h);
0064 seed = combine(seed, hash(element.value()));
0065 }
0066 return seed;
0067 }
0068
0069 case BasicJsonType::value_t::array:
0070 {
0071 auto seed = combine(type, j.size());
0072 for (const auto& element : j)
0073 {
0074 seed = combine(seed, hash(element));
0075 }
0076 return seed;
0077 }
0078
0079 case BasicJsonType::value_t::string:
0080 {
0081 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
0082 return combine(type, h);
0083 }
0084
0085 case BasicJsonType::value_t::boolean:
0086 {
0087 const auto h = std::hash<bool> {}(j.template get<bool>());
0088 return combine(type, h);
0089 }
0090
0091 case BasicJsonType::value_t::number_integer:
0092 {
0093 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
0094 return combine(type, h);
0095 }
0096
0097 case BasicJsonType::value_t::number_unsigned:
0098 {
0099 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
0100 return combine(type, h);
0101 }
0102
0103 case BasicJsonType::value_t::number_float:
0104 {
0105 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
0106 return combine(type, h);
0107 }
0108
0109 case BasicJsonType::value_t::binary:
0110 {
0111 auto seed = combine(type, j.get_binary().size());
0112 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
0113 seed = combine(seed, h);
0114 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
0115 for (const auto byte : j.get_binary())
0116 {
0117 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
0118 }
0119 return seed;
0120 }
0121
0122 default:
0123 JSON_ASSERT(false);
0124 return 0;
0125 }
0126 }
0127
0128 }
0129 NLOHMANN_JSON_NAMESPACE_END