123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- // __ _____ _____ _____
- // __| | __| | | | JSON for Modern C++
- // | | |__ | | | | | | version 3.11.3
- // |_____|_____|_____|_|___| https://github.com/nlohmann/json
- //
- // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
- // SPDX-License-Identifier: MIT
- #pragma once
- #include <cstdint> // uint8_t
- #include <cstddef> // size_t
- #include <functional> // hash
- #include <nlohmann/detail/abi_macros.hpp>
- #include <nlohmann/detail/value_t.hpp>
- NLOHMANN_JSON_NAMESPACE_BEGIN
- namespace detail
- {
- // boost::hash_combine
- inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
- {
- seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
- return seed;
- }
- /*!
- @brief hash a JSON value
- The hash function tries to rely on std::hash where possible. Furthermore, the
- type of the JSON value is taken into account to have different hash values for
- null, 0, 0U, and false, etc.
- @tparam BasicJsonType basic_json specialization
- @param j JSON value to hash
- @return hash value of j
- */
- template<typename BasicJsonType>
- 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;
- const auto type = static_cast<std::size_t>(j.type());
- switch (j.type())
- {
- case BasicJsonType::value_t::null:
- case BasicJsonType::value_t::discarded:
- {
- return combine(type, 0);
- }
- case BasicJsonType::value_t::object:
- {
- auto seed = combine(type, j.size());
- for (const auto& element : j.items())
- {
- const auto h = std::hash<string_t> {}(element.key());
- seed = combine(seed, h);
- seed = combine(seed, hash(element.value()));
- }
- return seed;
- }
- case BasicJsonType::value_t::array:
- {
- auto seed = combine(type, j.size());
- for (const auto& element : j)
- {
- seed = combine(seed, hash(element));
- }
- return seed;
- }
- case BasicJsonType::value_t::string:
- {
- const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
- return combine(type, h);
- }
- case BasicJsonType::value_t::boolean:
- {
- const auto h = std::hash<bool> {}(j.template get<bool>());
- return combine(type, h);
- }
- case BasicJsonType::value_t::number_integer:
- {
- const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
- return combine(type, h);
- }
- case BasicJsonType::value_t::number_unsigned:
- {
- const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
- return combine(type, h);
- }
- case BasicJsonType::value_t::number_float:
- {
- const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
- return combine(type, h);
- }
- case BasicJsonType::value_t::binary:
- {
- auto seed = combine(type, j.get_binary().size());
- const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
- seed = combine(seed, h);
- seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
- for (const auto byte : j.get_binary())
- {
- seed = combine(seed, std::hash<std::uint8_t> {}(byte));
- }
- return seed;
- }
- default: // LCOV_EXCL_LINE
- JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
- return 0; // LCOV_EXCL_LINE
- }
- }
- } // namespace detail
- NLOHMANN_JSON_NAMESPACE_END
|