Horizon
hash.hpp
1 #pragma once
2 
3 #include <cstddef> // size_t, uint8_t
4 #include <functional> // hash
5 
6 namespace nlohmann
7 {
8 namespace detail
9 {
10 
11 // boost::hash_combine
12 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
13 {
14  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
15  return seed;
16 }
17 
29 template<typename BasicJsonType>
30 std::size_t hash(const BasicJsonType& j)
31 {
32  using string_t = typename BasicJsonType::string_t;
33  using number_integer_t = typename BasicJsonType::number_integer_t;
34  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
35  using number_float_t = typename BasicJsonType::number_float_t;
36 
37  const auto type = static_cast<std::size_t>(j.type());
38  switch (j.type())
39  {
40  case BasicJsonType::value_t::null:
41  case BasicJsonType::value_t::discarded:
42  {
43  return combine(type, 0);
44  }
45 
46  case BasicJsonType::value_t::object:
47  {
48  auto seed = combine(type, j.size());
49  for (const auto& element : j.items())
50  {
51  const auto h = std::hash<string_t> {}(element.key());
52  seed = combine(seed, h);
53  seed = combine(seed, hash(element.value()));
54  }
55  return seed;
56  }
57 
58  case BasicJsonType::value_t::array:
59  {
60  auto seed = combine(type, j.size());
61  for (const auto& element : j)
62  {
63  seed = combine(seed, hash(element));
64  }
65  return seed;
66  }
67 
68  case BasicJsonType::value_t::string:
69  {
70  const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
71  return combine(type, h);
72  }
73 
74  case BasicJsonType::value_t::boolean:
75  {
76  const auto h = std::hash<bool> {}(j.template get<bool>());
77  return combine(type, h);
78  }
79 
80  case BasicJsonType::value_t::number_integer:
81  {
82  const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
83  return combine(type, h);
84  }
85 
87  {
88  const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
89  return combine(type, h);
90  }
91 
93  {
94  const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
95  return combine(type, h);
96  }
97 
99  {
100  auto seed = combine(type, j.get_binary().size());
101  const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
102  seed = combine(seed, h);
103  seed = combine(seed, j.get_binary().subtype());
104  for (const auto byte : j.get_binary())
105  {
106  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
107  }
108  return seed;
109  }
110 
111  default: // LCOV_EXCL_LINE
112  JSON_ASSERT(false); // LCOV_EXCL_LINE
113  }
114 }
115 
116 } // namespace detail
117 } // namespace nlohmann
@ binary
binary array (ordered collection of bytes)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: hash.hpp:30
namespace for Niels Lohmann
Definition: adl_serializer.hpp:9