Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add transparent comparator and perfect forwarding support to find() and count() #795

Merged
merged 9 commits into from
Oct 27, 2017
39 changes: 29 additions & 10 deletions src/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -7589,9 +7597,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<StringType>;
#endif
using object_t = ObjectType<StringType,
basic_json,
std::less<StringType>,
object_comparator_t,
AllocatorType<std::pair<const StringType,
basic_json>>>;

Expand Down Expand Up @@ -9842,7 +9858,7 @@ class basic_json
#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
#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
#endif
, int >::type = 0 >
Expand Down Expand Up @@ -10868,7 +10884,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
Expand All @@ -10880,29 +10896,31 @@ class basic_json

@since version 1.0.0
*/
iterator find(typename object_t::key_type key)
template<typename KeyT>
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<KeyT>(key));
}

return result;
}

/*!
@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();

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;
Expand All @@ -10929,10 +10947,11 @@ class basic_json

@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 is_object() ? m_value.object->count(key) : 0;
return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
}

/// @}
Expand Down