From 5c08a52fd6830d1fa37ca2cc24308e9e55218c3d Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 4 Nov 2021 16:38:40 +0100 Subject: [PATCH] :recycle: overwork std specializations (#3121) --- include/nlohmann/json.hpp | 24 +++++++-------- single_include/nlohmann/json.hpp | 24 +++++++-------- test/src/unit-hash.cpp | 52 +++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 27 deletions(-) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index cce508bed..9a00b3226 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -8936,20 +8936,19 @@ std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j) // nonmember support // /////////////////////// -// specialization of std::swap, and std::hash -namespace std +namespace std // NOLINT(cert-dcl58-cpp) { /// hash value for JSON objects -template<> -struct hash +NLOHMANN_BASIC_JSON_TPL_DECLARATION +struct hash { /*! @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); } @@ -8959,7 +8958,7 @@ struct hash /// @note: do not remove the space after '<', /// see https://github.com/nlohmann/json/pull/679 template<> -struct less<::nlohmann::detail::value_t> +struct less< ::nlohmann::detail::value_t> { /*! @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 -@since version 1.0.0 +@since version 1.0.0, extended for arbitrary basic_json types in 3.10.5. */ -template<> -inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name) - is_nothrow_move_constructible::value&& // NOLINT(misc-redundant-expression) - is_nothrow_move_assignable::value - ) +NLOHMANN_BASIC_JSON_TPL_DECLARATION +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::value&& // NOLINT(misc-redundant-expression) + is_nothrow_move_assignable::value) { j1.swap(j2); } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 58c7a1d47..4ca17ca4a 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -26437,20 +26437,19 @@ std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j) // nonmember support // /////////////////////// -// specialization of std::swap, and std::hash -namespace std +namespace std // NOLINT(cert-dcl58-cpp) { /// hash value for JSON objects -template<> -struct hash +NLOHMANN_BASIC_JSON_TPL_DECLARATION +struct hash { /*! @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); } @@ -26460,7 +26459,7 @@ struct hash /// @note: do not remove the space after '<', /// see https://github.com/nlohmann/json/pull/679 template<> -struct less<::nlohmann::detail::value_t> +struct less< ::nlohmann::detail::value_t> { /*! @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 -@since version 1.0.0 +@since version 1.0.0, extended for arbitrary basic_json types in 3.10.5. */ -template<> -inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name) - is_nothrow_move_constructible::value&& // NOLINT(misc-redundant-expression) - is_nothrow_move_assignable::value - ) +NLOHMANN_BASIC_JSON_TPL_DECLARATION +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::value&& // NOLINT(misc-redundant-expression) + is_nothrow_move_assignable::value) { j1.swap(j2); } diff --git a/test/src/unit-hash.cpp b/test/src/unit-hash.cpp index 28970d129..7abec52d1 100644 --- a/test/src/unit-hash.cpp +++ b/test/src/unit-hash.cpp @@ -31,10 +31,11 @@ SOFTWARE. #include using json = nlohmann::json; +using ordered_json = nlohmann::ordered_json; #include -TEST_CASE("hash") +TEST_CASE("hash") { // Collect hashes for different JSON values and make sure that they are distinct // We cannot compare against fixed values, because the implementation of @@ -82,3 +83,52 @@ TEST_CASE("hash") CHECK(hashes.size() == 21); } + +TEST_CASE("hash") +{ + // 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 hashes; + + // null + hashes.insert(std::hash {}(ordered_json(nullptr))); + + // boolean + hashes.insert(std::hash {}(ordered_json(true))); + hashes.insert(std::hash {}(ordered_json(false))); + + // string + hashes.insert(std::hash {}(ordered_json(""))); + hashes.insert(std::hash {}(ordered_json("foo"))); + + // number + hashes.insert(std::hash {}(ordered_json(0))); + hashes.insert(std::hash {}(ordered_json(unsigned(0)))); + + hashes.insert(std::hash {}(ordered_json(-1))); + hashes.insert(std::hash {}(ordered_json(0.0))); + hashes.insert(std::hash {}(ordered_json(42.23))); + + // array + hashes.insert(std::hash {}(ordered_json::array())); + hashes.insert(std::hash {}(ordered_json::array({1, 2, 3}))); + + // object + hashes.insert(std::hash {}(ordered_json::object())); + hashes.insert(std::hash {}(ordered_json::object({{"foo", "bar"}}))); + + // binary + hashes.insert(std::hash {}(ordered_json::binary({}))); + hashes.insert(std::hash {}(ordered_json::binary({}, 0))); + hashes.insert(std::hash {}(ordered_json::binary({}, 42))); + hashes.insert(std::hash {}(ordered_json::binary({1, 2, 3}))); + hashes.insert(std::hash {}(ordered_json::binary({1, 2, 3}, 0))); + hashes.insert(std::hash {}(ordered_json::binary({1, 2, 3}, 42))); + + // discarded + hashes.insert(std::hash {}(ordered_json(ordered_json::value_t::discarded))); + + CHECK(hashes.size() == 21); +}