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

Conversation

jseward
Copy link
Contributor

@jseward jseward commented Oct 21, 2017

This avoids unnecessary string copies and allocation on often used find() if std::string_view is supported.

NOTE: currently only implemented for MSVS 2017, should be easily enabled for other compilers as well but don't have them available.

This avoids unnecessary string copies on often used
find().
@jseward jseward changed the title Add string_view support Add std::string_view support Oct 21, 2017
@jseward
Copy link
Contributor Author

jseward commented Oct 21, 2017

Found some chat on #464 for similar issues. Hijacked the solution there for this new functionality.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 1a66679 on jseward:develop into 33df325 on nlohmann:develop.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling d468f8c on jseward:develop into 33df325 on nlohmann:develop.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling d468f8c on jseward:develop into 33df325 on nlohmann:develop.

@trilogy-service-ro
Copy link

Can one of the admins verify this patch?

@nlohmann
Copy link
Owner

@trilogy-service-ro Please stop spamming PRs.

src/json.hpp Outdated
basic_json>>>;

using object_comparator_key_t = typename object_t::key_type;
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to do the transparent comparator across the board for C++14 and higher?

src/json.hpp Outdated
@@ -10894,9 +10920,9 @@ class basic_json

/*!
@brief find an element in a JSON object
@copydoc find(typename object_t::key_type)
@copydoc find(object_transparent_comparator_key_t)
Copy link
Contributor

@gregmarr gregmarr Oct 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this type (with transparent in it) defined? Just a typo here?

src/json.hpp Outdated
@@ -10929,7 +10955,7 @@ class basic_json

@since version 1.0.0
*/
size_type count(typename object_t::key_type key) const
size_type count(object_comparator_key_t key) const
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the find and count functions be better as templates with perfect forwarding, so we can find or count directly anything that the underlying object class can find or count?

Instead implement @gregmarr's PR comments that perfect forwarding should be used. Also cleaned up cpp language standard detection.
@jseward jseward changed the title Add std::string_view support Add transparent comparator and perfect forwarding support to find() and count() Oct 23, 2017
@jseward jseward changed the title Add transparent comparator and perfect forwarding support to find() and count() Add transparent comparator and perfect forwarding support to find() and count() if CPP 14 is detected Oct 23, 2017
@jseward jseward changed the title Add transparent comparator and perfect forwarding support to find() and count() if CPP 14 is detected Add transparent comparator and perfect forwarding support to find() and count() Oct 23, 2017
@jseward
Copy link
Contributor Author

jseward commented Oct 23, 2017

@gregmarr thanks for the great feedback. I've implemented your suggested changes

src/json.hpp Outdated
@@ -110,11 +110,11 @@ SOFTWARE.
#endif

// string_view support
#if defined(_MSC_VER) && defined(_HAS_CXX17) && _HAS_CXX17 == 1
#define JSON_USE_STRING_VIEW
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSC_VER) && _MSC_VER > 1900 && defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use __has_include instead?

src/json.hpp Outdated
@copydoc find(typename object_t::key_type)
*/
template<typename KeyT>
iterator find(KeyT&& key)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we define those perfect-forwarded overloads for C++11 as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The templated member functions don't exist in 11. They were added in 14.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but we could keep those overloads in C++11, they will call the regular comparators which will perform implicit conversions, as for:

std::cout << std::multiplies<int>{}(2.0f, 2.0f) << std::endl;

I haven't tested my suggestion though, so it might very well be bogus.

Copy link
Contributor

@gregmarr gregmarr Oct 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My first thought was that it might be weird for users that aren't familiar with the difference in capabilities between std::map in 11 and 14 to have the templated type that only works with things implicitly convertible to the key type, but maybe that's not an issue, as you'd get the same issue with anything that isn't comparable with the key type with the 14 version. The STL kept the non-template find() and count(), but likely only for backwards compat. If it works, I think it would be better with just the templated versions. If we can't eliminate the fixed type versions, we should add const & to them to match the std::map versions. Right now we make a copy unnecessarily. (I just noticed this now.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the suggestion, pushed changes to just have perfect-forwarding only

if(MSVC_VERSION GREATER_EQUAL 1910)
# Enable c++17 support in Visual Studio 2017 (for testing perfect forwarding and transparent comparator in find() / count())
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
endif()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC Appveyor already runs with VS2017, you might want to put that flag in the Appveyor file?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed we have three configurations for AppVeyor:

  • MSVC 2015
  • MSVC 2017
  • MSVC 2017 + /permissive- /std:c++latest /utf-8

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah nice, didn't realize that thanks. I'll this remove this then.

@nlohmann
Copy link
Owner

Sorry - AppVeyor fails because of a recent change of mine. I shall fix this.

@nlohmann
Copy link
Owner

The develop version now compiles without problems with AppVeyor.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 33c6511 on jseward:develop into 33df325 on nlohmann:develop.

@gregmarr
Copy link
Contributor

@jseward You're welcome. I'm glad it worked out.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 992c836 on jseward:develop into 33df325 on nlohmann:develop.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 992c836 on jseward:develop into 33df325 on nlohmann:develop.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 992c836 on jseward:develop into 33df325 on nlohmann:develop.

@jseward
Copy link
Contributor Author

jseward commented Oct 25, 2017

travis-ci failing with:

==> Cloning https://github.com/nlohmann/json.git
Cloning into '/Users/travis/Library/Caches/Homebrew/nlohmann_json--git'...
remote: Counting objects: 1279, done.
remote: Compressing objects: 100% (605/605), done.
error: RPC failed; curl 56 SSLRead() return error -36
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
Error: Failed to download resource "nlohmann_json"
Failure while executing: git clone --depth 1 --branch develop https://github.com/nlohmann/json.git /Users/travis/Library/Caches/Homebrew/nlohmann_json--git
Error: Testing requires the latest version of nlohmann/json/nlohmann_json

don't notice an obvious way to retry

@nlohmann
Copy link
Owner

Travis' support for macOS is a bit flaky. I restarted the job.

Copy link
Owner

@nlohmann nlohmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@nlohmann nlohmann self-assigned this Oct 27, 2017
@nlohmann nlohmann added this to the Release 3.0.0 milestone Oct 27, 2017
@nlohmann nlohmann merged commit 77f8e2f into nlohmann:develop Oct 27, 2017
@nlohmann
Copy link
Owner

Thanks a lot!

nlohmann added a commit that referenced this pull request Oct 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants