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

Implement P2508R1 basic_format_string, format_string, wformat_string #3074

Merged
merged 2 commits into from
Sep 15, 2022

Conversation

cpplearner
Copy link
Contributor

This implements P2508R1.

Fixes #2937.

The paper mentions that

This doesn’t strictly have to be a DR, and could certainly just be a C++23 feature.

But I strongly hope that this can be applied to C++20, so the signature of std::format does not change between C++20 and C++23.

@cpplearner cpplearner requested a review from a team as a code owner September 3, 2022 18:26
@StephanTLavavej StephanTLavavej added format C++20/23 format cxx23 C++23 feature labels Sep 3, 2022
@StephanTLavavej StephanTLavavej added this to Initial Review in Code Reviews via automation Sep 3, 2022
@frederick-vs-ja
Copy link
Contributor

Ah... I've started working on this in an alternative way which derives basic_format_string from _Basic_format_string and only adds it in C++23 mode. Although it seemly needs additional test coverage for the newly added get member function.

@frederick-vs-ja
Copy link
Contributor

Or alternatively, should we implement basic_format_string as an alias template to avoid additional non-reservered names in C++20 mode?
Although this is currently non-conforming, but IMO it's reasonable to form a DR (targeting C++23 only) to allow basic_format_string to be an alias template.

@cpplearner
Copy link
Contributor Author

I will implement the alternative approaches if I have to, but I really hope that we don't need them.

@StephanTLavavej StephanTLavavej added the decision needed We need to choose something before working on this label Sep 6, 2022
@StephanTLavavej
Copy link
Member

Maintainer decision needed: implementing this unconditionally will introduce these new identifiers in C++20 mode, making conflicts possible.

My initial reaction is that this should be guarded for C++23, as we generally consider the introduction of new identifiers to be a bright line. However, perhaps the signature change is sufficiently invasive, and the risk of conflict sufficiently low, that implementing this "downlevel" would be reasonable. Certainly, something that affects only C++20 is much less risky than something that goes back to C++14/17.

One more note: we won't be backporting further changes to VS 2019 16.11.x except in highly critical cases; I believe that this is an additional reason to avoid changing C++20 behavior.

@cpplearner
Copy link
Contributor Author

Note that P2419R2 "Clarify handling of encodings in localized formatting of chrono types" was implemented for C++20. If P2508R1 is guarded for C++23, then it needs to be decided whether __cpp_lib_format will have value 202207 in C++20 mode.

@frederick-vs-ja
Copy link
Contributor

It's a bit strange that while P2419R2 looks like a DR (resolving LWG-3565) but P2508R1 doesn't, both papers bump the same feature-test macro. I plan to contact LWG for clarification.

@StephanTLavavej StephanTLavavej removed the decision needed We need to choose something before working on this label Sep 7, 2022
@StephanTLavavej
Copy link
Member

Charlie and I talked about this at the weekly maintainer meeting and we're ok with the current approach of implementing this in C++20 mode - thanks!

@mordante
Copy link
Contributor

mordante commented Sep 8, 2022

It's a bit strange that while P2419R2 looks like a DR (resolving LWG-3565) but P2508R1 doesn't, both papers bump the same feature-test macro. I plan to contact LWG for clarification.

There is currently a discussion on the SG-10 mailing list about this and there is an LWG issue
https://cplusplus.github.io/LWG/issue3750

FYI libc++ has also implemented this paper in C++20 mode. This is shipped in LLVM 15.

@barcharcraz
Copy link
Member

FYI libc++ has also implemented this paper in C++20 mode. This is shipped in LLVM 15.

Yeah, if libc++ already did it in C++20 mode it seems like we should too. Gating it behind C++23 is likely to cause much more pain for people using multiple compilers than the new identifier.

@mordante
Copy link
Contributor

mordante commented Sep 8, 2022

In libc++ we never shipped the exposition only version. So it was easy to decide to do it this way.

@StephanTLavavej
Copy link
Member

Looks good - I see nothing missing here, and the risk of linker errors when mixing old and new code is low. (Previously, the type couldn't be directly named, so it appeared as a function parameter and would be implicitly constructed. The risk would be higher if functions could have easily returned the type.)

The only thing I considered commenting on was that the struct begins with a public: section, when we usually rely on the default, but this is a defensible style choice (as the exposition-only data member is private: which is good). No change requested.

@StephanTLavavej StephanTLavavej moved this from Initial Review to Final Review in Code Reviews Sep 9, 2022
Copy link
Contributor

@strega-nil-ms strega-nil-ms left a comment

Choose a reason for hiding this comment

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

This LGTM, but I'm leaving in Final Review so @barcharcraz can take a look.

Comment on lines +1438 to +1459
template <class charT>
constexpr void test_basic_format_string() {
{
basic_format_string<charT> fmt_str = basic_string_view{STR("meow")};
assert(fmt_str.get() == STR("meow"));
}
{
basic_format_string<charT, double, int> fmt_str = STR("{:a} {:b}");
assert(fmt_str.get() == STR("{:a} {:b}"));
}
}

constexpr bool test_format_string() {
test_basic_format_string<char>();
test_basic_format_string<wchar_t>();

static_assert(is_same_v<format_string<int*>, basic_format_string<char, int*>>);
static_assert(is_same_v<wformat_string<int*>, basic_format_string<wchar_t, int*>>);

return true;
}

Copy link
Member

Choose a reason for hiding this comment

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

These tests are pretty low value IMO, but since you already wrote them I'm fine with using them.

Copy link
Member

@barcharcraz barcharcraz left a comment

Choose a reason for hiding this comment

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

This looks correct to me. if this somehow causes massive amounts of horrible compatibility badness we can back it out

@strega-nil-ms strega-nil-ms moved this from Final Review to Ready To Merge in Code Reviews Sep 14, 2022
@StephanTLavavej
Copy link
Member

I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed.

@StephanTLavavej StephanTLavavej merged commit 67a96a9 into microsoft:main Sep 15, 2022
Code Reviews automation moved this from Ready To Merge to Done Sep 15, 2022
@StephanTLavavej
Copy link
Member

Thanks for implementing this C++23 feature and increasing <format> usability! 😻 🎉 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cxx23 C++23 feature format C++20/23 format
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

P2508R1 basic_format_string, format_string, wformat_string
7 participants