Merge pull request #795 from jseward/develop

Add transparent comparator and perfect forwarding support to find() and count()
This commit is contained in:
Niels Lohmann 2017-10-27 11:47:23 +02:00 committed by GitHub
commit 77f8e2f987

View file

@ -109,6 +109,14 @@ SOFTWARE.
#define JSON_UNLIKELY(x) x #define JSON_UNLIKELY(x) x
#endif #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 @brief namespace for Niels Lohmann
@see https://github.com/nlohmann @see https://github.com/nlohmann
@ -7566,9 +7574,17 @@ class basic_json
7159](http://rfc7159.net/rfc7159), because any order implements the 7159](http://rfc7159.net/rfc7159), because any order implements the
specified "unordered" nature of JSON objects. 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<StringType>;
#endif
using object_t = ObjectType<StringType, using object_t = ObjectType<StringType,
basic_json, basic_json,
std::less<StringType>, object_comparator_t,
AllocatorType<std::pair<const StringType, AllocatorType<std::pair<const StringType,
basic_json>>>; basic_json>>>;
@ -9819,7 +9835,7 @@ class basic_json
#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
#endif #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<ValueType, typename std::string_view>::value and not std::is_same<ValueType, typename std::string_view>::value
#endif #endif
, int >::type = 0 > , int >::type = 0 >
@ -10845,7 +10861,7 @@ class basic_json
@note This method always returns @ref end() when executed on a JSON type @note This method always returns @ref end() when executed on a JSON type
that is not an object. 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 @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 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 @since version 1.0.0
*/ */
iterator find(typename object_t::key_type key) template<typename KeyT>
iterator find(KeyT&& key)
{ {
auto result = end(); auto result = end();
if (is_object()) if (is_object())
{ {
result.m_it.object_iterator = m_value.object->find(key); result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
} }
return result; return result;
@ -10871,15 +10888,16 @@ class basic_json
/*! /*!
@brief find an element in a JSON object @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<typename KeyT>
const_iterator find(KeyT&& key) const
{ {
auto result = cend(); auto result = cend();
if (is_object()) if (is_object())
{ {
result.m_it.object_iterator = m_value.object->find(key); result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
} }
return result; return result;
@ -10906,10 +10924,11 @@ class basic_json
@since version 1.0.0 @since version 1.0.0
*/ */
size_type count(typename object_t::key_type key) const template<typename KeyT>
size_type count(KeyT&& key) const
{ {
// return 0 for all nonobject types // return 0 for all nonobject types
return is_object() ? m_value.object->count(key) : 0; return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
} }
/// @} /// @}