diff --git a/doc/mkdocs/docs/api/basic_json/default_object_comparator_t.md b/doc/mkdocs/docs/api/basic_json/default_object_comparator_t.md new file mode 100644 index 000000000..265a9d385 --- /dev/null +++ b/doc/mkdocs/docs/api/basic_json/default_object_comparator_t.md @@ -0,0 +1,18 @@ +# nlohmann::basic_json::default_object_comparator_t + +```cpp +using default_object_comparator_t = std::less; // until C++14 + +using default_object_comparator_t = std::less<>; // since C++14 +``` + +The default comparator used by [`object_t`](object_t.md). + +Since C++14 a transparent comparator is used which prevents unnecessary string construction. + +The actual comparator used depends on [`object_t`](object_t.md) and can be obtained via +[`object_comparator_t`](object_comparator_t.md). + +## Version history + +- Added in version 3.11.0. diff --git a/doc/mkdocs/docs/api/basic_json/index.md b/doc/mkdocs/docs/api/basic_json/index.md index 286fea2b4..68ac063ff 100644 --- a/doc/mkdocs/docs/api/basic_json/index.md +++ b/doc/mkdocs/docs/api/basic_json/index.md @@ -128,6 +128,7 @@ The class satisfies the following concept requirements: - [**array_t**](array_t.md) - type for arrays - [**binary_t**](binary_t.md) - type for binary arrays - [**boolean_t**](boolean_t.md) - type for booleans +- [**default_object_comparator_t**](default_object_comparator_t.md) - default comparator for objects - [**number_float_t**](number_float_t.md) - type for numbers (floating-point) - [**number_integer_t**](number_integer_t.md) - type for numbers (integer) - [**number_unsigned_t**](number_unsigned_t.md) - type for numbers (unsigned) diff --git a/doc/mkdocs/docs/api/basic_json/object_comparator_t.md b/doc/mkdocs/docs/api/basic_json/object_comparator_t.md index e2bc79d05..6c64b6453 100644 --- a/doc/mkdocs/docs/api/basic_json/object_comparator_t.md +++ b/doc/mkdocs/docs/api/basic_json/object_comparator_t.md @@ -1,16 +1,16 @@ # nlohmann::basic_json::object_comparator_t -```cpp -using object_comparator_t = std::less; // until C++14 -using object_comparator_t = std::less<>; // since C++14 +```cpp +using object_comparator_t = typename object_t::key_compare; +// or +using object_comparator_t = default_object_comparator_t; ``` -The comparator used in [`object_t`](object_t.md). - -When C++14 is detected, a transparent comparator is used which, when combined with perfect forwarding on find() and -count() calls, prevents unnecessary string construction. +The comparator used by [`object_t`](object_t.md). Defined as `#!cpp typename object_t::key_compare` if available, +and [`default_object_comparator_t`](default_object_comparator_t.md) otherwise. ## Version history -- Unknown. +- Added in version 3.0.0. +- Changed to be conditionally defined as `#!cpp typename object_t::key_compare` or `default_object_comparator_t` in version 3.11.0. diff --git a/doc/mkdocs/docs/api/basic_json/object_t.md b/doc/mkdocs/docs/api/basic_json/object_t.md index d4bea15aa..67b3bb78c 100644 --- a/doc/mkdocs/docs/api/basic_json/object_t.md +++ b/doc/mkdocs/docs/api/basic_json/object_t.md @@ -3,7 +3,7 @@ ```cpp using object_t = ObjectType>>; ``` @@ -52,7 +52,7 @@ std::map< > ``` -See [`object_comparator_t`](object_comparator_t.md) for more information. +See [`default_object_comparator_t`](default_object_comparator_t.md) for more information. #### Behavior diff --git a/doc/mkdocs/mkdocs.yml b/doc/mkdocs/mkdocs.yml index 59f0ae700..302e827cf 100644 --- a/doc/mkdocs/mkdocs.yml +++ b/doc/mkdocs/mkdocs.yml @@ -97,6 +97,7 @@ nav: - 'count': api/basic_json/count.md - 'crbegin': api/basic_json/crbegin.md - 'crend': api/basic_json/crend.md + - 'default_object_comparator_t': api/basic_json/default_object_comparator_t.md - 'diff': api/basic_json/diff.md - 'dump': api/basic_json/dump.md - 'emplace': api/basic_json/emplace.md diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index 376c00a09..c111b5520 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -160,6 +160,24 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> T>::value; }; +template +using detect_key_compare = typename T::key_compare; + +template +struct has_key_compare : std::integral_constant::value> {}; + +// obtains the actual object key comparator +template +struct actual_object_comparator +{ + using object_t = typename BasicJsonType::object_t; + using object_comparator_t = typename BasicJsonType::default_object_comparator_t; + using type = typename std::conditional < has_key_compare::value, + typename object_t::key_compare, object_comparator_t>::type; +}; + +template +using actual_object_comparator_t = typename actual_object_comparator::type; /////////////////// // is_ functions // diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 1a2da8d45..51eb73778 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -350,21 +350,23 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// the template arguments passed to class @ref basic_json. /// @{ - /// @brief object key comparator type - /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/ + /// @brief default object key comparator type + /// The actual object key comparator type (@ref object_comparator_t) may be + /// different. + /// @sa https://json.nlohmann.me/api/basic_json/default_object_comparator_t/ #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<>; + // use of transparent comparator avoids unnecessary repeated construction of temporaries + // in functions involving lookup by key with types other than object_t::key_type (aka. StringType) + using default_object_comparator_t = std::less<>; #else - using object_comparator_t = std::less; + using default_object_comparator_t = std::less; #endif /// @brief a type for an object /// @sa https://json.nlohmann.me/api/basic_json/object_t/ using object_t = ObjectType>>; @@ -396,6 +398,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @sa https://json.nlohmann.me/api/basic_json/binary_t/ using binary_t = nlohmann::byte_container_with_subtype; + /// @brief object key comparator type + /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/ + using object_comparator_t = detail::actual_object_comparator_t; + /// @} private: diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index e806a8f00..cb48ffe59 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3295,6 +3295,24 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> T>::value; }; +template +using detect_key_compare = typename T::key_compare; + +template +struct has_key_compare : std::integral_constant::value> {}; + +// obtains the actual object key comparator +template +struct actual_object_comparator +{ + using object_t = typename BasicJsonType::object_t; + using object_comparator_t = typename BasicJsonType::default_object_comparator_t; + using type = typename std::conditional < has_key_compare::value, + typename object_t::key_compare, object_comparator_t>::type; +}; + +template +using actual_object_comparator_t = typename actual_object_comparator::type; /////////////////// // is_ functions // @@ -17812,21 +17830,23 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// the template arguments passed to class @ref basic_json. /// @{ - /// @brief object key comparator type - /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/ + /// @brief default object key comparator type + /// The actual object key comparator type (@ref object_comparator_t) may be + /// different. + /// @sa https://json.nlohmann.me/api/basic_json/default_object_comparator_t/ #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<>; + // use of transparent comparator avoids unnecessary repeated construction of temporaries + // in functions involving lookup by key with types other than object_t::key_type (aka. StringType) + using default_object_comparator_t = std::less<>; #else - using object_comparator_t = std::less; + using default_object_comparator_t = std::less; #endif /// @brief a type for an object /// @sa https://json.nlohmann.me/api/basic_json/object_t/ using object_t = ObjectType>>; @@ -17858,6 +17878,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @sa https://json.nlohmann.me/api/basic_json/binary_t/ using binary_t = nlohmann::byte_container_with_subtype; + /// @brief object key comparator type + /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/ + using object_comparator_t = detail::actual_object_comparator_t; + /// @} private: