diff --git a/src/json.hpp b/src/json.hpp index cf1134a66..d23d85b30 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -109,6 +109,14 @@ SOFTWARE. #define JSON_UNLIKELY(x) x #endif +// cpp language standard detection +#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 +#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 +#endif + /*! @brief namespace for Niels Lohmann @see https://github.com/nlohmann @@ -7566,9 +7574,17 @@ class basic_json 7159](http://rfc7159.net/rfc7159), because any order implements the specified "unordered" nature of JSON objects. */ + +#if defined(JSON_HAS_CPP_14) + // Use transparent comparator if possible, combined with perfect forwarding + // on find() and count() calls prevents unnecessary string construction. + using object_comparator_t = std::less<>; +#else + using object_comparator_t = std::less; +#endif using object_t = ObjectType, + object_comparator_t, AllocatorType>>; @@ -9819,7 +9835,7 @@ class basic_json #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 and not std::is_same>::value #endif -#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSC_VER) && _MSC_VER >1900 && defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 +#if defined(JSON_HAS_CPP_17) and not std::is_same::value #endif , int >::type = 0 > @@ -10845,7 +10861,7 @@ class basic_json @note This method always returns @ref end() when executed on a JSON type that is not an object. - @param[in] key key value of the element to search for + @param[in] key key value of the element to search for. @return Iterator to an element with key equivalent to @a key. If no such element is found or the JSON value is not an object, past-the-end (see @@ -10857,13 +10873,14 @@ class basic_json @since version 1.0.0 */ - iterator find(typename object_t::key_type key) + template + iterator find(KeyT&& key) { auto result = end(); if (is_object()) { - result.m_it.object_iterator = m_value.object->find(key); + result.m_it.object_iterator = m_value.object->find(std::forward(key)); } return result; @@ -10871,15 +10888,16 @@ class basic_json /*! @brief find an element in a JSON object - @copydoc find(typename object_t::key_type) + @copydoc find(KeyT&&) */ - const_iterator find(typename object_t::key_type key) const + template + const_iterator find(KeyT&& key) const { auto result = cend(); if (is_object()) { - result.m_it.object_iterator = m_value.object->find(key); + result.m_it.object_iterator = m_value.object->find(std::forward(key)); } return result; @@ -10906,10 +10924,11 @@ class basic_json @since version 1.0.0 */ - size_type count(typename object_t::key_type key) const + template + size_type count(KeyT&& key) const { // return 0 for all nonobject types - return is_object() ? m_value.object->count(key) : 0; + return is_object() ? m_value.object->count(std::forward(key)) : 0; } /// @}