"bbbb" "cccc";
"cccc";
-**AlwaysBreakTemplateDeclarations** (``bool``)
- If ``true``, always break after the ``template<...>`` of a template
- declaration.
+**AlwaysBreakTemplateDeclarations** (``BreakTemplateDeclarationsStyle``)
+ The template declaration breaking style to use.
+
+ Possible values:
+
+ * ``BTDS_No`` (in configuration: ``No``)
+ Do not force break before declaration.
+ ``PenaltyBreakTemplateDeclaration`` is taken into account.
+
+ .. code-block:: c++
+
+ template <typename T> T foo() {
+ }
+ template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa,
+ int bbbbbbbbbbbbbbbbbbbbb) {
+ }
+
+ * ``BTDS_MultiLine`` (in configuration: ``MultiLine``)
+ Force break after template declaration only when the following
+ declaration spans multiple lines.
+
+ .. code-block:: c++
+
+ template <typename T> T foo() {
+ }
+ template <typename T>
+ T foo(int aaaaaaaaaaaaaaaaaaaaa,
+ int bbbbbbbbbbbbbbbbbbbbb) {
+ }
+
+ * ``BTDS_Yes`` (in configuration: ``Yes``)
+ Always break after template declaration.
+
+ .. code-block:: c++
+
+ template <typename T>
+ T foo() {
+ }
+ template <typename T>
+ T foo(int aaaaaaaaaaaaaaaaaaaaa,
+ int bbbbbbbbbbbbbbbbbbbbb) {
+ }
- .. code-block:: c++
- true: false:
- template <typename T> vs. template <typename T> class C {};
- class C {};
**BinPackArguments** (``bool``)
If ``false``, a function call's arguments will either be all on the
**PenaltyBreakString** (``unsigned``)
The penalty for each line break introduced inside a string literal.
+**PenaltyBreakTemplateDeclaration** (``unsigned``)
+ The penalty for breaking after template declaration.
+
**PenaltyExcessCharacter** (``unsigned``)
The penalty for each character outside of the column limit.
/// \endcode
bool AlwaysBreakBeforeMultilineStrings;
- /// If ``true``, always break after the ``template<...>`` of a template
- /// declaration.
- /// \code
- /// true: false:
- /// template <typename T> vs. template <typename T> class C {};
- /// class C {};
- /// \endcode
- bool AlwaysBreakTemplateDeclarations;
+ /// Different ways to break after the template declaration.
+ enum BreakTemplateDeclarationsStyle {
+ /// Do not force break before declaration.
+ /// ``PenaltyBreakTemplateDeclaration`` is taken into account.
+ /// \code
+ /// template <typename T> T foo() {
+ /// }
+ /// template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa,
+ /// int bbbbbbbbbbbbbbbbbbbbb) {
+ /// }
+ /// \endcode
+ BTDS_No,
+ /// Force break after template declaration only when the following
+ /// declaration spans multiple lines.
+ /// \code
+ /// template <typename T> T foo() {
+ /// }
+ /// template <typename T>
+ /// T foo(int aaaaaaaaaaaaaaaaaaaaa,
+ /// int bbbbbbbbbbbbbbbbbbbbb) {
+ /// }
+ /// \endcode
+ BTDS_MultiLine,
+ /// Always break after template declaration.
+ /// \code
+ /// template <typename T>
+ /// T foo() {
+ /// }
+ /// template <typename T>
+ /// T foo(int aaaaaaaaaaaaaaaaaaaaa,
+ /// int bbbbbbbbbbbbbbbbbbbbb) {
+ /// }
+ /// \endcode
+ BTDS_Yes
+ };
+
+ /// The template declaration breaking style to use.
+ BreakTemplateDeclarationsStyle AlwaysBreakTemplateDeclarations;
/// If ``false``, a function call's arguments will either be all on the
/// same line or will have one line each.
/// The penalty for each line break introduced inside a string literal.
unsigned PenaltyBreakString;
+ /// The penalty for breaking after template declaration.
+ unsigned PenaltyBreakTemplateDeclaration;
+
/// The penalty for each character outside of the column limit.
unsigned PenaltyExcessCharacter;
PenaltyBreakString == R.PenaltyBreakString &&
PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
+ PenaltyBreakTemplateDeclaration ==
+ R.PenaltyBreakTemplateDeclaration &&
PointerAlignment == R.PointerAlignment &&
RawStringFormats == R.RawStringFormats &&
SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
Style.Language == FormatStyle::LK_JavaScript))
return true;
+ // If the template declaration spans multiple lines, force wrap before the
+ // function/class declaration
+ if (Previous.ClosesTemplateDeclaration &&
+ State.Stack.back().BreakBeforeParameter)
+ return true;
+
if (State.Column <= NewLineColumn)
return false;
// for cases where the entire line does not fit on a single line as a
// different LineFormatter would be used otherwise.
if (Previous.ClosesTemplateDeclaration)
- return true;
+ return Style.AlwaysBreakTemplateDeclarations != FormatStyle::BTDS_No;
if (Previous.is(TT_FunctionAnnotationRParen))
return true;
if (Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) &&
}
};
+template <>
+struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> {
+ static void enumeration(IO &IO, FormatStyle::BreakTemplateDeclarationsStyle &Value) {
+ IO.enumCase(Value, "No", FormatStyle::BTDS_No);
+ IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine);
+ IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes);
+
+ // For backward compatibility.
+ IO.enumCase(Value, "false", FormatStyle::BTDS_MultiLine);
+ IO.enumCase(Value, "true", FormatStyle::BTDS_Yes);
+ }
+};
+
template <>
struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> {
static void
IO.mapOptional("PenaltyBreakFirstLessLess",
Style.PenaltyBreakFirstLessLess);
IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
+ IO.mapOptional("PenaltyBreakTemplateDeclaration",
+ Style.PenaltyBreakTemplateDeclaration);
IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
Style.PenaltyReturnTypeOnItsOwnLine);
LLVMStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
- LLVMStyle.AlwaysBreakTemplateDeclarations = false;
+ LLVMStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_MultiLine;
LLVMStyle.BinPackArguments = true;
LLVMStyle.BinPackParameters = true;
LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
LLVMStyle.PenaltyExcessCharacter = 1000000;
LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19;
+ LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational;
LLVMStyle.DisableFormat = false;
LLVMStyle.SortIncludes = true;
GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
GoogleStyle.AllowShortLoopsOnASingleLine = true;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
- GoogleStyle.AlwaysBreakTemplateDeclarations = true;
+ GoogleStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
GoogleStyle.DerivePointerAlignment = true;
GoogleStyle.IncludeStyle.IncludeCategories = {
MozillaStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_TopLevel;
MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
FormatStyle::DRTBS_TopLevel;
- MozillaStyle.AlwaysBreakTemplateDeclarations = true;
+ MozillaStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
MozillaStyle.BinPackParameters = false;
MozillaStyle.BinPackArguments = false;
MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla;
return 2;
return 1;
}
+ if (Left.ClosesTemplateDeclaration)
+ return Style.PenaltyBreakTemplateDeclaration;
if (Left.is(TT_ConditionalExpr))
return prec::Conditional;
prec::Level Level = Left.getPrecedence();
if (Right.Previous->ClosesTemplateDeclaration &&
Right.Previous->MatchingParen &&
Right.Previous->MatchingParen->NestingLevel == 0 &&
- Style.AlwaysBreakTemplateDeclarations)
+ Style.AlwaysBreakTemplateDeclarations == FormatStyle::BTDS_Yes)
return true;
if (Right.is(TT_CtorInitializerComma) &&
Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
" const typename aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaa);");
FormatStyle AlwaysBreak = getLLVMStyle();
- AlwaysBreak.AlwaysBreakTemplateDeclarations = true;
+ AlwaysBreak.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
verifyFormat("template <typename T>\nclass C {};", AlwaysBreak);
verifyFormat("template <typename T>\nvoid f();", AlwaysBreak);
verifyFormat("template <typename T>\nvoid f() {}", AlwaysBreak);
"public:\n"
" E *f();\n"
"};");
+
+ FormatStyle NeverBreak = getLLVMStyle();
+ NeverBreak.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_No;
+ verifyFormat("template <typename T> class C {};", NeverBreak);
+ verifyFormat("template <typename T> void f();", NeverBreak);
+ verifyFormat("template <typename T> void f() {}", NeverBreak);
+ verifyFormat("template <typename T>\nvoid foo(aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbb) {}",
+ NeverBreak);
+ verifyFormat("void aaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " bbbbbbbbbbbbbbbbbbbbbbbbbbbb>(\n"
+ " ccccccccccccccccccccccccccccccccccccccccccccccc);",
+ NeverBreak);
+ verifyFormat("template <template <typename> class Fooooooo,\n"
+ " template <typename> class Baaaaaaar>\n"
+ "struct C {};",
+ NeverBreak);
+ verifyFormat("template <typename T> // T can be A, B or C.\n"
+ "struct C {};",
+ NeverBreak);
+ verifyFormat("template <enum E> class A {\n"
+ "public:\n"
+ " E *f();\n"
+ "};", NeverBreak);
+ NeverBreak.PenaltyBreakTemplateDeclaration = 100;
+ verifyFormat("template <typename T> void\nfoo(aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbb) {}",
+ NeverBreak);
}
TEST_F(FormatTest, WrapsTemplateParameters) {
CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine);
CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine);
CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
- CHECK_PARSE_BOOL(AlwaysBreakTemplateDeclarations);
CHECK_PARSE_BOOL(BinPackArguments);
CHECK_PARSE_BOOL(BinPackParameters);
CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations);
PenaltyBreakAssignment, 1234u);
CHECK_PARSE("PenaltyBreakBeforeFirstCallParameter: 1234",
PenaltyBreakBeforeFirstCallParameter, 1234u);
+ CHECK_PARSE("PenaltyBreakTemplateDeclaration: 1234",
+ PenaltyBreakTemplateDeclaration, 1234u);
CHECK_PARSE("PenaltyExcessCharacter: 1234", PenaltyExcessCharacter, 1234u);
CHECK_PARSE("PenaltyReturnTypeOnItsOwnLine: 1234",
PenaltyReturnTypeOnItsOwnLine, 1234u);
AlwaysBreakAfterReturnType,
FormatStyle::RTBS_TopLevelDefinitions);
+ Style.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: No", AlwaysBreakTemplateDeclarations,
+ FormatStyle::BTDS_No);
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: MultiLine", AlwaysBreakTemplateDeclarations,
+ FormatStyle::BTDS_MultiLine);
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: Yes", AlwaysBreakTemplateDeclarations,
+ FormatStyle::BTDS_Yes);
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: false", AlwaysBreakTemplateDeclarations,
+ FormatStyle::BTDS_MultiLine);
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: true", AlwaysBreakTemplateDeclarations,
+ FormatStyle::BTDS_Yes);
+
Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: None",
AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_None);