Clang-format splits template-template parameters

Sorry if this is the wrong tag, I saw a clang-tidy one but not a clang-format one.

I have this class template:

template <typename AAA, typename BBB, typename CCC, template <typename> class DDD>
class SomeTemplate;

With this .clang-format file:

BasedOnStyle: llvm

AccessModifierOffset: -4
AlignConsecutiveBitFields: Consecutive
AlignEscapedNewlines: Right
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortFunctionsOnASingleLine: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BreakBeforeBraces: Custom
BreakConstructorInitializers: BeforeComma
BraceWrapping:
  BeforeElse: true
  BeforeCatch: true
ColumnLimit: 80
ConstructorInitializerAllOnOneLineOrOnePerLine: true
IndentWidth: 4
NamespaceIndentation: None
PenaltyBreakAssignment: 60
PenaltyBreakBeforeFirstCallParameter: 175
PointerAlignment: Left
QualifierAlignment: Custom
QualifierOrder: ['static', 'inline', 'constexpr', 'type', 'const', 'volatile']
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterTemplateKeyword: true
SpacesBeforeTrailingComments: 2
SpacesInSquareBrackets: false

it gets formatted as:

template <typename AAA,
          typename BBB,
          typename CCC,
          template <typename>
          class DDD>
class SomeTemplate;

Notably, the DDD parameter is split across two lines instead of being formatted on one line as template <typename> class DDD

This is very confusing formatting choice, since class DDD is a valid template parameter in of itself.

Changing BinPackParameters to true gets me this formatting:

template <typename AAA, typename BBB, typename CCC,
          template <typename> class DDD>
class SomeTemplate;

Which puts all of DDD on the same line, but it also puts all the other parameters together on the same line, which is precisely what we wanted to avoid with setting BinPackParameters to false.

Is there some other clang-format configuration that does the right thing here? Is this basically just a bug with how BinPackParameters is interpreted?

1 Like