-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
[feature request] requires clause in functions (concepts TS) #31514
Comments
assigned to @HazardyKnusperkeks |
Ditto Poke, poke. Now that C++20 has been sent out for (what will likely be) its final round of balloting, it would be a good time to work on supporting requires-clauses in clang-format. Think of all the poor, suffering STL maintainers! |
I've started to look into the concepts and requires keywords and how clang-format interacts with them (its doesn't really) I'd like @Casey to start with a slightly simpler example (if we could start without the comment that might help) For the following would you expect it to be formatted like this? template <class I, class S> or something else? I'm trying to look for something of a common starting place between what I see in both https://github.com/CaseyCarter/cmcstl2 |
Today, I'd format this as: template <class I, class S>
requires Sentinel<S, I>()
constexpr void advance(I& i, S bound) noexcept(noexcept(++i != bound)) {
while (i != bound) {
++i;
}
} with the requires-clause indented once relative to the template declaration, and continuation lines one indent deeper: template <class I, class S>
requires Sentinel<S, I>() && // ...
&& OtherConcept1<I> && // ...
&& OtherConcept2<I> && // ...
&& OtherConcept3<I> && // ...
constexpr void advance(I& i, S bound) noexcept(noexcept(++i != bound)) {
while (i != bound) {
++i;
}
} which probably follows from how clang normally wraps expressions across lines. I try to format trailing requires-clauses exactly as you've put the noexcept-specifier in the example, but wrapping the whole thing onto the next line if it won't fit on the primary declaration line and only splitting if the requires-clause itself is longer than one line: template <class I>
void f(I i) requires Concept1<I> && Concept2<i> {
// ...
}
template <class I>
long_return_type g(I i)
requires Concept1<I> && Concept2<i> && VeryVeryVeryVeryLongConcept<I> {
// ...
}
template <class I>
long_return_type h(I i) requires Concept1<I> && Concept2<i> &&
VeryVeryVeryVeryLongConcept<I> && OtherLongConcept<I> {
// ...
}
Please ignore cmcstl2: there a few different styles there that we experimented with over the years, and it was never really made consistent. range-v3 is even worse: its style represents a set of compromises to get the least offensive output from clang-format. I have no idea how libstdc++ is formatting their concepts usage, but they have C++20 Ranges implemented so they may have an interesting counterpoint to my style. |
I'm working on it. |
The review link would be: https://reviews.llvm.org/D113319 template <typename T>
requires
C<T>
class ... will not be supported. If you are really interested in it you can look at some older revision where I had a basic handling of that and try to get it working. |
Please update this, either as solved, or what is still wished and we can discuss that. |
Let's go ahead and call this closed. Anyone who wants changes can file a new issue. |
Extended Description
This code
gets formatted into:
I don't see a reason why the options specified in #32165 shouldn't apply here as well.
Also: https://github.com/CaseyCarter/cmcstl2/blob/43b63f6846d80bcd1867f512519bc18841bd961e/include/stl2/detail/iterator/operations.hpp#L25
this code:
gets formatted into
(Note how the constexpr keywords is not aligned with the template keyword).
The text was updated successfully, but these errors were encountered: