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

Feat/explicit conversion operator #1559

Merged

Conversation

theodelrieu
Copy link
Contributor

@theodelrieu theodelrieu commented Apr 4, 2019

Here it is!

Thanks to @gracicot, who found a good solution to #958, I'm finally attempting to solve it.

This PR introduces a CMake option: JSON_ExplicitConversions, defaulted to OFF.

To help users move away from the implicit conversion operator, a warning will be issued each time it is used. This warning can be silenced by users defining JSON_USE_IMPLICIT_CONVERSIONS.

On the other hand, defining JSON_USE_EXPLICIT_CONVERSIONS will very likely break code, but will ease the transition to the next major version, where only explicit conversion operator will be kept.

Meanwhile, I've removed every implicit conversion from the library's code, including tests.
It might be a good idea to add a short ifdefed test case, which tests implicit conversions (to avoid duplicating a lot of test code).

With explicit conversions, we can also remove the constraints that are present today, e.g. forbidding conversion from char, std::initializer_list<char>. Note that this has not been done in this PR.

I think this change is more suited to be released in a minor version, so we might release 3.6.2 first?

Pull request checklist

Read the Contribution Guidelines for detailed information.

  • Changes are described in the pull request, or an existing issue is referenced.
  • The test suite compiles and runs without error.
  • Code coverage is 100%. Test cases can be added by editing the test suite.
  • The source code is amalgamated; that is, after making changes to the sources in the include/nlohmann directory, run make amalgamate to create the single-header file single_include/nlohmann/json.hpp. The whole process is described here.

@theodelrieu theodelrieu force-pushed the feat/explicit_conversion_operator branch from edc99df to 5ec90c8 Compare April 4, 2019 12:41
@theodelrieu
Copy link
Contributor Author

Where is the LGTM config file?

Copy link
Contributor

@gracicot gracicot left a comment

Choose a reason for hiding this comment

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

Yeah, sorry I didn't had the time to submit the patch. Thanks for the submission!

My proposed solution was not as perfect as I thought, see my comment. Other than that, the diff seems fine for me!

#ifndef JSON_USE_EXPLICIT_CONVERSIONS
#define JSON_EXPLICIT
#ifndef JSON_USE_IMPLICIT_CONVERSIONS
#warning Implicit conversions are being deprecated and will be \
Copy link
Contributor

Choose a reason for hiding this comment

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

I realized that the #warning statement is not standard, and not supported on msvc. There is some solution like #pragma message() but it's not a real warning.

I think we could use [[deprecated("...")]] or the msvc non standard __declspec(deprecated("...")) for earlier versions in that case.

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've added JSON_DEPRECATED_MSG, and tried building the tests by removing the Wno-deprecated warnings, it works \o/

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you, the patch is great now. I would just wait for @nlohmann to do a review too and merge it!

Copy link
Owner

Choose a reason for hiding this comment

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

I like the idea of having a switch for the conversions, but I am still not convinced that implicit conversions should be deprecated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The main reason is because it is broken today. The pile of issues related to #958 is a good indicator of that. Not to mention the why is quite hard to grasp.

The required changes are quite minimal as well:

std::string s;
s = j;
// becomes
std::string s;
j.get_to(s);

std::string s = j;
// becomes
std::string s(j);

Copy link
Contributor

@gracicot gracicot Apr 5, 2019

Choose a reason for hiding this comment

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

After thinking about it I think @nlohmann is right on not deprecate right now (I still think it should eventually). The compile switch must be there for a while before any deprecation, and the documentation should also rely on explicit conversion and it should recommend enabling the switch.

I would like to see the implicit operator be deprecated too but I also agree that even though the change in the syntax is minimal, its use is widespread so it must be done very gradually.

Edit: moved the example into the issue

@theodelrieu theodelrieu force-pushed the feat/explicit_conversion_operator branch from 5ec90c8 to fb833af Compare April 4, 2019 14:08
@coveralls
Copy link

coveralls commented Apr 4, 2019

Coverage Status

Coverage remained the same at 100.0% when pulling 7973293 on theodelrieu:feat/explicit_conversion_operator into 2cd10a7 on nlohmann:develop.

@nlohmann
Copy link
Owner

nlohmann commented Apr 4, 2019

Where is the LGTM config file?

There is no config file. Here is a link to the log: https://lgtm.com/projects/g/nlohmann/json/logs/rev/pr-e7a2ac9be19e57d05404374d62bf6a8ab3794bfe/lang:cpp/stage:Build%20merge_d94187b754143b1064d1f7bcd3000e3db0419555. Strange that the test fails.

@theodelrieu
Copy link
Contributor Author

But where do you define how to build the library?

@theodelrieu theodelrieu force-pushed the feat/explicit_conversion_operator branch 4 times, most recently from 54a0f6b to 79639b5 Compare April 8, 2019 13:37
@theodelrieu
Copy link
Contributor Author

Ok, the LGTM build uses default CMake arguments, therefore it builds with the implicit conversions.
All the other builds use explicit conversions.

@nlohmann do you wish to do like with JSON_MultipleHeaders? i.e. define a variable in the CI files.

@stale
Copy link

stale bot commented May 9, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label May 9, 2019
@theodelrieu
Copy link
Contributor Author

It would be nice to merge this PR and discuss what is the long-term plan after.

@stale stale bot removed the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label May 9, 2019
@stale
Copy link

stale bot commented Jun 8, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Jun 8, 2019
@nlohmann nlohmann removed the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Jun 15, 2019
@stale
Copy link

stale bot commented Jul 8, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Jul 8, 2019
@nlohmann nlohmann removed the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Jul 13, 2019
@theodelrieu
Copy link
Contributor Author

@nlohmann Shall we merge this PR now that 3.7.0 has been released?

@stale
Copy link

stale bot commented Aug 29, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Aug 29, 2019
@nlohmann nlohmann added pinned and removed state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated labels Sep 2, 2019
@gracicot
Copy link
Contributor

gracicot commented Oct 2, 2019

Since tackling the conversion operator is being candidate for version 4.0.0, I'd vote to add the deprecation back when JSON_ExplicitConversions is off.

If we want to use explicit conversion on the next major version, deprecation and the switch is the first step to transition the community.

@theodelrieu theodelrieu force-pushed the feat/explicit_conversion_operator branch from 8ce2e52 to ba4ee31 Compare December 2, 2019 09:19
@theodelrieu
Copy link
Contributor Author

@nlohmann Seems good finally 🙏

test/src/unit-conversions.cpp Outdated Show resolved Hide resolved
include/nlohmann/detail/meta/type_traits.hpp Show resolved Hide resolved
test/src/unit-conversions.cpp Show resolved Hide resolved
CMakeLists.txt Outdated
@@ -24,6 +24,7 @@ endif ()
option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ON)
option(JSON_Install "Install CMake targets during install step." ON)
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF)
option(JSON_ExplicitConversions "Enable explicit conversion operator" OFF)
Copy link
Owner

Choose a reason for hiding this comment

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

I'm still struggling with the wording. To me, the switch "enable explicit conversion" sounds like an additional feature. Instead, it breaks existing code, because the assumed implicit conversions do not work any longer. If the code already only used explicit conversions, then flipping the switch does not change anything.

@theodelrieu
Copy link
Contributor Author

@nlohmann About your last comment: I can swap the CMake option definition

@theodelrieu theodelrieu force-pushed the feat/explicit_conversion_operator branch from a3e6f5c to cc74efb Compare July 22, 2020 07:49
@theodelrieu theodelrieu force-pushed the feat/explicit_conversion_operator branch from cc74efb to 7973293 Compare July 22, 2020 08:49
@theodelrieu
Copy link
Contributor Author

@nlohmann GitHub was unreachable again, sigh. Can you restart the job please? 🙏 (https://travis-ci.org/github/nlohmann/json/jobs/710669524#L5359)

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 Jul 22, 2020
@nlohmann nlohmann added this to the Release 3.8.1 milestone Jul 22, 2020
@nlohmann nlohmann linked an issue Jul 22, 2020 that may be closed by this pull request
@theodelrieu
Copy link
Contributor Author

@nlohmann It seems appveyor is stuck as well 🤔

@nlohmann
Copy link
Owner

No, it's just slow...

@@ -24,6 +24,7 @@ endif ()
option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ON)
option(JSON_Install "Install CMake targets during install step." ON)
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF)
option(JSON_ImplicitConversions "Enable implicit conversions" ON)
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe put period at end of description for consistency's sake.

@gracicot
Copy link
Contributor

I wonder if this can be removed to re-enable conversions to std::string_view once we switch to explicit conversions:

    && !std::is_same<ValueType, typename std::string_view>::value

I think it was disabled because of a problem with string views and visual studio, but I'm not sure. If someone can find the issue/pull request, that would be awesome.

@nlohmann
Copy link
Owner

@gracicot Was this changed in this PR?

@gracicot
Copy link
Contributor

gracicot commented Jul 23, 2020

@gracicot Was this changed in this PR?

No. The pull request mentioned that this hasn't been done forstd::initializer_list but I was wondering if std::string_view was worth to do. Right now json_value.get<std: string_view>() works, but not the conversion and is_gettable returns false for it.

@nlohmann
Copy link
Owner

No. The pull request mentioned that this hasn't been done forstd::initializer_list but I was wondering if std::string_view was worth to do. Right now json_value.get<std: string_view>() works, but not the conversion and is_gettable returns false for it.

I see. Let's handle this in a follow-up issue. This PR has been open for too long...

@nlohmann nlohmann merged commit a048b72 into nlohmann:develop Jul 23, 2020
@nlohmann
Copy link
Owner

Thank you all so much!

@nlohmann
Copy link
Owner


🔖 Release item

This issue/PR will be part of the next release of the library. This template helps preparing the release notes.

Type

  • ✨ New Feature
  • 🐛 Bug Fix
  • ⚡️ Improvement
  • 🔨 Further Change
  • 🔥 Deprecated function

Description


@theodelrieu theodelrieu deleted the feat/explicit_conversion_operator branch July 23, 2020 08:38
@theodelrieu
Copy link
Contributor Author

@gracicot I think all these type of explicit SFINAE disabling can be removed when using explicit conversions. IIRC there is one for char as well somewhere.

@gracicot
Copy link
Contributor

Thank you so much! 🎉

@tlemo
Copy link

tlemo commented Jul 23, 2020

Thanks @theodelrieu for driving this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

operator T() considered harmful
7 participants