Skip to content

Commit 77f8e2f

Browse files
authored
Merge pull request #795 from jseward/develop
Add transparent comparator and perfect forwarding support to find() and count()
2 parents c215b77 + 992c836 commit 77f8e2f

1 file changed

Lines changed: 29 additions & 10 deletions

File tree

src/json.hpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ SOFTWARE.
109109
#define JSON_UNLIKELY(x) x
110110
#endif
111111

112+
// cpp language standard detection
113+
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
114+
#define JSON_HAS_CPP_17
115+
#define JSON_HAS_CPP_14
116+
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
117+
#define JSON_HAS_CPP_14
118+
#endif
119+
112120
/*!
113121
@brief namespace for Niels Lohmann
114122
@see https://github.com/nlohmann
@@ -7566,9 +7574,17 @@ class basic_json
75667574
7159](http://rfc7159.net/rfc7159), because any order implements the
75677575
specified "unordered" nature of JSON objects.
75687576
*/
7577+
7578+
#if defined(JSON_HAS_CPP_14)
7579+
// Use transparent comparator if possible, combined with perfect forwarding
7580+
// on find() and count() calls prevents unnecessary string construction.
7581+
using object_comparator_t = std::less<>;
7582+
#else
7583+
using object_comparator_t = std::less<StringType>;
7584+
#endif
75697585
using object_t = ObjectType<StringType,
75707586
basic_json,
7571-
std::less<StringType>,
7587+
object_comparator_t,
75727588
AllocatorType<std::pair<const StringType,
75737589
basic_json>>>;
75747590

@@ -9819,7 +9835,7 @@ class basic_json
98199835
#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
98209836
and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
98219837
#endif
9822-
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSC_VER) && _MSC_VER >1900 && defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
9838+
#if defined(JSON_HAS_CPP_17)
98239839
and not std::is_same<ValueType, typename std::string_view>::value
98249840
#endif
98259841
, int >::type = 0 >
@@ -10845,7 +10861,7 @@ class basic_json
1084510861
@note This method always returns @ref end() when executed on a JSON type
1084610862
that is not an object.
1084710863
10848-
@param[in] key key value of the element to search for
10864+
@param[in] key key value of the element to search for.
1084910865
1085010866
@return Iterator to an element with key equivalent to @a key. If no such
1085110867
element is found or the JSON value is not an object, past-the-end (see
@@ -10857,29 +10873,31 @@ class basic_json
1085710873
1085810874
@since version 1.0.0
1085910875
*/
10860-
iterator find(typename object_t::key_type key)
10876+
template<typename KeyT>
10877+
iterator find(KeyT&& key)
1086110878
{
1086210879
auto result = end();
1086310880

1086410881
if (is_object())
1086510882
{
10866-
result.m_it.object_iterator = m_value.object->find(key);
10883+
result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
1086710884
}
1086810885

1086910886
return result;
1087010887
}
1087110888

1087210889
/*!
1087310890
@brief find an element in a JSON object
10874-
@copydoc find(typename object_t::key_type)
10891+
@copydoc find(KeyT&&)
1087510892
*/
10876-
const_iterator find(typename object_t::key_type key) const
10893+
template<typename KeyT>
10894+
const_iterator find(KeyT&& key) const
1087710895
{
1087810896
auto result = cend();
1087910897

1088010898
if (is_object())
1088110899
{
10882-
result.m_it.object_iterator = m_value.object->find(key);
10900+
result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
1088310901
}
1088410902

1088510903
return result;
@@ -10906,10 +10924,11 @@ class basic_json
1090610924
1090710925
@since version 1.0.0
1090810926
*/
10909-
size_type count(typename object_t::key_type key) const
10927+
template<typename KeyT>
10928+
size_type count(KeyT&& key) const
1091010929
{
1091110930
// return 0 for all nonobject types
10912-
return is_object() ? m_value.object->count(key) : 0;
10931+
return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
1091310932
}
1091410933

1091510934
/// @}

0 commit comments

Comments
 (0)