♻️ overwork std specializations (#3121)

This commit is contained in:
Niels Lohmann 2021-11-04 16:38:40 +01:00 committed by GitHub
parent 5d87c4d409
commit 5c08a52fd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 27 deletions

View File

@ -8936,20 +8936,19 @@ std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
// nonmember support // // nonmember support //
/////////////////////// ///////////////////////
// specialization of std::swap, and std::hash namespace std // NOLINT(cert-dcl58-cpp)
namespace std
{ {
/// hash value for JSON objects /// hash value for JSON objects
template<> NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct hash<nlohmann::json> struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL>
{ {
/*! /*!
@brief return a hash value for a JSON object @brief return a hash value for a JSON object
@since version 1.0.0 @since version 1.0.0, extended for arbitrary basic_json types in 3.10.5.
*/ */
std::size_t operator()(const nlohmann::json& j) const std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
{ {
return nlohmann::detail::hash(j); return nlohmann::detail::hash(j);
} }
@ -8959,7 +8958,7 @@ struct hash<nlohmann::json>
/// @note: do not remove the space after '<', /// @note: do not remove the space after '<',
/// see https://github.com/nlohmann/json/pull/679 /// see https://github.com/nlohmann/json/pull/679
template<> template<>
struct less<::nlohmann::detail::value_t> struct less< ::nlohmann::detail::value_t>
{ {
/*! /*!
@brief compare two value_t enum values @brief compare two value_t enum values
@ -8978,13 +8977,12 @@ struct less<::nlohmann::detail::value_t>
/*! /*!
@brief exchanges the values of two JSON objects @brief exchanges the values of two JSON objects
@since version 1.0.0 @since version 1.0.0, extended for arbitrary basic_json types in 3.10.5.
*/ */
template<> NLOHMANN_BASIC_JSON_TPL_DECLARATION
inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name) inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
is_nothrow_move_constructible<nlohmann::json>::value&& // NOLINT(misc-redundant-expression) is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
is_nothrow_move_assignable<nlohmann::json>::value is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
)
{ {
j1.swap(j2); j1.swap(j2);
} }

View File

@ -26437,20 +26437,19 @@ std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
// nonmember support // // nonmember support //
/////////////////////// ///////////////////////
// specialization of std::swap, and std::hash namespace std // NOLINT(cert-dcl58-cpp)
namespace std
{ {
/// hash value for JSON objects /// hash value for JSON objects
template<> NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct hash<nlohmann::json> struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL>
{ {
/*! /*!
@brief return a hash value for a JSON object @brief return a hash value for a JSON object
@since version 1.0.0 @since version 1.0.0, extended for arbitrary basic_json types in 3.10.5.
*/ */
std::size_t operator()(const nlohmann::json& j) const std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
{ {
return nlohmann::detail::hash(j); return nlohmann::detail::hash(j);
} }
@ -26460,7 +26459,7 @@ struct hash<nlohmann::json>
/// @note: do not remove the space after '<', /// @note: do not remove the space after '<',
/// see https://github.com/nlohmann/json/pull/679 /// see https://github.com/nlohmann/json/pull/679
template<> template<>
struct less<::nlohmann::detail::value_t> struct less< ::nlohmann::detail::value_t>
{ {
/*! /*!
@brief compare two value_t enum values @brief compare two value_t enum values
@ -26479,13 +26478,12 @@ struct less<::nlohmann::detail::value_t>
/*! /*!
@brief exchanges the values of two JSON objects @brief exchanges the values of two JSON objects
@since version 1.0.0 @since version 1.0.0, extended for arbitrary basic_json types in 3.10.5.
*/ */
template<> NLOHMANN_BASIC_JSON_TPL_DECLARATION
inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name) inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
is_nothrow_move_constructible<nlohmann::json>::value&& // NOLINT(misc-redundant-expression) is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
is_nothrow_move_assignable<nlohmann::json>::value is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
)
{ {
j1.swap(j2); j1.swap(j2);
} }

View File

@ -31,10 +31,11 @@ SOFTWARE.
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
using json = nlohmann::json; using json = nlohmann::json;
using ordered_json = nlohmann::ordered_json;
#include <set> #include <set>
TEST_CASE("hash") TEST_CASE("hash<nlohmann::json>")
{ {
// Collect hashes for different JSON values and make sure that they are distinct // Collect hashes for different JSON values and make sure that they are distinct
// We cannot compare against fixed values, because the implementation of // We cannot compare against fixed values, because the implementation of
@ -82,3 +83,52 @@ TEST_CASE("hash")
CHECK(hashes.size() == 21); CHECK(hashes.size() == 21);
} }
TEST_CASE("hash<nlohmann::ordered_json>")
{
// Collect hashes for different JSON values and make sure that they are distinct
// We cannot compare against fixed values, because the implementation of
// std::hash may differ between compilers.
std::set<std::size_t> hashes;
// null
hashes.insert(std::hash<ordered_json> {}(ordered_json(nullptr)));
// boolean
hashes.insert(std::hash<ordered_json> {}(ordered_json(true)));
hashes.insert(std::hash<ordered_json> {}(ordered_json(false)));
// string
hashes.insert(std::hash<ordered_json> {}(ordered_json("")));
hashes.insert(std::hash<ordered_json> {}(ordered_json("foo")));
// number
hashes.insert(std::hash<ordered_json> {}(ordered_json(0)));
hashes.insert(std::hash<ordered_json> {}(ordered_json(unsigned(0))));
hashes.insert(std::hash<ordered_json> {}(ordered_json(-1)));
hashes.insert(std::hash<ordered_json> {}(ordered_json(0.0)));
hashes.insert(std::hash<ordered_json> {}(ordered_json(42.23)));
// array
hashes.insert(std::hash<ordered_json> {}(ordered_json::array()));
hashes.insert(std::hash<ordered_json> {}(ordered_json::array({1, 2, 3})));
// object
hashes.insert(std::hash<ordered_json> {}(ordered_json::object()));
hashes.insert(std::hash<ordered_json> {}(ordered_json::object({{"foo", "bar"}})));
// binary
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({})));
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({}, 0)));
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({}, 42)));
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({1, 2, 3})));
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({1, 2, 3}, 0)));
hashes.insert(std::hash<ordered_json> {}(ordered_json::binary({1, 2, 3}, 42)));
// discarded
hashes.insert(std::hash<ordered_json> {}(ordered_json(ordered_json::value_t::discarded)));
CHECK(hashes.size() == 21);
}