LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 32165 - [feature request] requires clause in class templates (Concepts TS)
Summary: [feature request] requires clause in class templates (Concepts TS)
Status: CONFIRMED
Alias: None
Product: clang
Classification: Unclassified
Component: Formatter (show other bugs)
Version: trunk
Hardware: All All
: P enhancement
Assignee: Björn Schäpers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-03-07 02:48 PST by Gonzalo BG
Modified: 2021-11-09 13:03 PST (History)
6 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gonzalo BG 2017-03-07 02:48:37 PST
The following code:

template <class T, class U, class... Rest>
  requires CommonReference<T, U>() 
struct common_reference<T, U, Rest...>
    : common_reference<common_reference_t<T, U>, Rest...> {};

is reformatted to 

template <class T, class U, class... Rest>
requires CommonReference<T, U>() struct common_reference<T, U, Rest...>
    : common_reference<common_reference_t<T, U>, Rest...> {};

because clang-format does not understand the requires keyword in class templates.

It should either be formatted to 

// A: requires clause in its own line: 
template <class T, class U, class... Rest>
  requires CommonReference<T, U>() 
struct common_reference<T, U, Rest...>
    : common_reference<common_reference_t<T, U>, Rest...> {};

// B: small require clause in line with template arguments 
template <class T, class U, class... Rest> requires CommonReference<T, U>() 
struct common_reference<T, U, Rest...>
    : common_reference<common_reference_t<T, U>, Rest...> {};


Also, long requires clauses are not handled properly

template <class T, class U, class... Rest>
    requires CommonReference<T, U>() && 
             CommonReference<T, U>() &&
             CommonReference<T, U>() 
struct common_reference<T, U, Rest...>
    : common_reference<common_reference_t<T, U>, Rest...> {};

is reformatted to:

template <class T, class U, class... Rest>
    requires CommonReference<T, U>() && CommonReference<T, U>() &&
    CommonReference<T, U>() struct common_reference<T, U, Rest...>
    : common_reference<common_reference_t<T, U>, Rest...> {};

Following customization parameters _might_ make sense, but I haven't given this much thought:

- indentation of the require clause with respect to the template arguments/struct (e.g. 1 space, 4 spaces...). Maybe we could reuse ContinuationIndentWidth/AccessModifierOffset for this, but I'd rather have it as a standalone option.
- AllowShortRequireClausesOnASingleLine: whether short requires clauses should be wrapped into the same line as the template arguments

And well probably stuff like BreakBeforeBinaryOperators should work here properly.
Comment 1 Gonzalo BG 2017-03-07 02:54:22 PST
The STL2 formats requires clauses in some places like this:

template <class T, class U, class... Rest>
requires 
        CommonReference<T, U>() && 
        CommonReference<T, U>() &&
        CommonReference<T, U>() 
struct common_reference<T, U, Rest...>
    : common_reference<common_reference_t<T, U>, Rest...> {};

That is: 

- RequiresClauseOffset = 0 (requires starts at the same place as template and struct)
- the first elements is put into the next line (there will need to be an option just for this).


https://github.com/CaseyCarter/cmcstl2/blob/49a0a43641f34ba1eb8170a1670a00ee3c0a8975/include/stl2/view/indirect.hpp#L24
Comment 2 Casey Carter 2020-03-02 12:48:55 PST
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!
Comment 3 Robert Russell 2021-11-04 05:13:13 PDT
In version 13 they have an IndentRequires that basically either indents or not.
Comment 4 Björn Schäpers 2021-11-09 13:03:30 PST
I'm working on it.