From aaef7cd2f88a1ee49b1ccc41d01770fc28a65b05 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 4 May 2021 12:35:07 +0200 Subject: [PATCH] :ok_hand: apply review comments --- include/nlohmann/detail/meta/type_traits.hpp | 32 ++++++++---- include/nlohmann/json.hpp | 22 ++++---- single_include/nlohmann/json.hpp | 54 ++++++++++++-------- 3 files changed, 68 insertions(+), 40 deletions(-) diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index 464c56e5a..e9bf81d08 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -434,16 +434,30 @@ template struct is_constructible_tuple> : conjunction...> {}; /// type to check if KeyType can be used as object key -template -struct is_key_type + +template +struct is_key_type_comparable { - static constexpr bool value = ( -#if defined(JSON_HAS_CPP_17) - std::is_same::type, std::string_view>::value || -#endif - std::is_convertible::value) - && !std::is_same::value - && !std::is_same::value; + static constexpr bool value = false; }; + +template +struct is_key_type_comparable(), std::declval())), +decltype(ComparatorType()(std::declval(), std::declval())) + >> +{ + static constexpr bool value = true; +}; + +template +struct is_usable_as_key_type +{ + static constexpr bool value = + is_key_type_comparable::value && + !std::is_same::value && + !std::is_same::value; +}; + } // namespace detail } // namespace nlohmann diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 8735fb2b1..8f4882fd5 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -3527,7 +3527,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec can be thrown.,at__object_t_key_type} */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value&& !std::is_same::type, json_pointer>::value > ... > + detail::is_usable_as_key_type::value&& !std::is_same::type, json_pointer>::value > ... > reference at(const KeyT& key) { // at only works for objects @@ -3576,7 +3576,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec at__object_t_key_type_const} */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value&& !std::is_same::type, json_pointer>::value > ... > + detail::is_usable_as_key_type::value&& !std::is_same::type, json_pointer>::value > ... > const_reference at(const KeyT& key) const { // at only works for objects @@ -3711,7 +3711,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 1.0.0; template KeyT added in version 3.10.0 */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value&& !std::is_same::type, json_pointer>::value > ... > + detail::is_usable_as_key_type::value&& !std::is_same::type, json_pointer>::value > ... > reference operator[](KeyT&& key) { // implicitly convert null value to an empty object @@ -3764,7 +3764,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 1.0.0; template KeyT added in version 3.10.0 */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value&& !std::is_same::type, json_pointer>::value > ... > + detail::is_usable_as_key_type::value&& !std::is_same::type, json_pointer>::value > ... > const_reference operator[](KeyT&& key) const { // operator[] only works for objects @@ -3833,7 +3833,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // using std::is_convertible in a std::enable_if will fail when using explicit conversions template < class KeyType, class ValueType, typename detail::enable_if_t < detail::is_getable::value - && !std::is_same::value&& detail::is_key_type::value > ... > + && !std::is_same::value&& detail::is_usable_as_key_type::value > ... > ValueType value(const KeyType& key, ValueType&& default_value) const { // at only works for objects @@ -3857,7 +3857,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const */ template < class KeyType, typename detail::enable_if_t < - detail::is_key_type::value > ... > + detail::is_usable_as_key_type::value > ... > string_t value(const KeyType& key, const char* default_value) const { return value(key, string_t(default_value)); @@ -4283,7 +4283,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 1.0.0; template added in version 3.10.0 */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value > ... > + detail::is_usable_as_key_type::value > ... > size_type erase(const KeyT& key) { // this erase only works for objects @@ -4379,7 +4379,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 1.0.0 */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value > ... > + detail::is_usable_as_key_type::value > ... > iterator find(const KeyT& key) { auto result = end(); @@ -4397,7 +4397,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @copydoc find(const KeyT&) */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value > ... > + detail::is_usable_as_key_type::value > ... > const_iterator find(const KeyT& key) const { auto result = cend(); @@ -4432,7 +4432,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 1.0.0 */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value > ... > + detail::is_usable_as_key_type::value > ... > size_type count(const KeyT& key) const { // return 0 for all nonobject types @@ -4465,7 +4465,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 3.6.0 */ template < class KeyT, typename detail::enable_if_t < - !std::is_same::type, json_pointer>::value&& detail::is_key_type::value > ... > + !std::is_same::type, json_pointer>::value&& detail::is_usable_as_key_type::value > ... > bool contains(const KeyT& key) const { return is_object() && m_value.object->find(key) != m_value.object->end(); diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 13179c82e..866fcb26e 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3829,17 +3829,31 @@ template struct is_constructible_tuple> : conjunction...> {}; /// type to check if KeyType can be used as object key -template -struct is_key_type + +template +struct is_key_type_comparable { - static constexpr bool value = ( -#if defined(JSON_HAS_CPP_17) - std::is_same::type, std::string_view>::value || -#endif - std::is_convertible::value) - && !std::is_same::value - && !std::is_same::value; + static constexpr bool value = false; }; + +template +struct is_key_type_comparable(), std::declval())), +decltype(ComparatorType()(std::declval(), std::declval())) + >> +{ + static constexpr bool value = true; +}; + +template +struct is_usable_as_key_type +{ + static constexpr bool value = + is_key_type_comparable::value && + !std::is_same::value && + !std::is_same::value; +}; + } // namespace detail } // namespace nlohmann @@ -20560,7 +20574,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec can be thrown.,at__object_t_key_type} */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value&& !std::is_same::type, json_pointer>::value > ... > + detail::is_usable_as_key_type::value&& !std::is_same::type, json_pointer>::value > ... > reference at(const KeyT& key) { // at only works for objects @@ -20609,7 +20623,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec at__object_t_key_type_const} */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value&& !std::is_same::type, json_pointer>::value > ... > + detail::is_usable_as_key_type::value&& !std::is_same::type, json_pointer>::value > ... > const_reference at(const KeyT& key) const { // at only works for objects @@ -20744,7 +20758,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 1.0.0; template KeyT added in version 3.10.0 */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value&& !std::is_same::type, json_pointer>::value > ... > + detail::is_usable_as_key_type::value&& !std::is_same::type, json_pointer>::value > ... > reference operator[](KeyT&& key) { // implicitly convert null value to an empty object @@ -20797,7 +20811,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 1.0.0; template KeyT added in version 3.10.0 */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value&& !std::is_same::type, json_pointer>::value > ... > + detail::is_usable_as_key_type::value&& !std::is_same::type, json_pointer>::value > ... > const_reference operator[](KeyT&& key) const { // operator[] only works for objects @@ -20866,7 +20880,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // using std::is_convertible in a std::enable_if will fail when using explicit conversions template < class KeyType, class ValueType, typename detail::enable_if_t < detail::is_getable::value - && !std::is_same::value&& detail::is_key_type::value > ... > + && !std::is_same::value&& detail::is_usable_as_key_type::value > ... > ValueType value(const KeyType& key, ValueType&& default_value) const { // at only works for objects @@ -20890,7 +20904,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const */ template < class KeyType, typename detail::enable_if_t < - detail::is_key_type::value > ... > + detail::is_usable_as_key_type::value > ... > string_t value(const KeyType& key, const char* default_value) const { return value(key, string_t(default_value)); @@ -21316,7 +21330,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 1.0.0; template added in version 3.10.0 */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value > ... > + detail::is_usable_as_key_type::value > ... > size_type erase(const KeyT& key) { // this erase only works for objects @@ -21412,7 +21426,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 1.0.0 */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value > ... > + detail::is_usable_as_key_type::value > ... > iterator find(const KeyT& key) { auto result = end(); @@ -21430,7 +21444,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @copydoc find(const KeyT&) */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value > ... > + detail::is_usable_as_key_type::value > ... > const_iterator find(const KeyT& key) const { auto result = cend(); @@ -21465,7 +21479,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 1.0.0 */ template < class KeyT, typename detail::enable_if_t < - detail::is_key_type::value > ... > + detail::is_usable_as_key_type::value > ... > size_type count(const KeyT& key) const { // return 0 for all nonobject types @@ -21498,7 +21512,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @since version 3.6.0 */ template < class KeyT, typename detail::enable_if_t < - !std::is_same::type, json_pointer>::value&& detail::is_key_type::value > ... > + !std::is_same::type, json_pointer>::value&& detail::is_usable_as_key_type::value > ... > bool contains(const KeyT& key) const { return is_object() && m_value.object->find(key) != m_value.object->end();