Как отформатировать инициализацию карты с помощью clang-формата?

Я пытаюсь внедрить clang-формат в довольно большой проект на C ++. Все идет так хорошо, за исключением нескольких случаев. Больше всего раздражает результат форматирования при инициализации карты. Я попытался найти флаги в формате clang или какое-либо решение, выполнив поиск в Google, но я ничего не нашел. Фрагмент проблемного кода:

// before formatting

const std::map<std::type_index, void *> functionMap{
  {typeid(DummyClassAAAAA), (bool (*)(const DummyClassAAAAA &, const DummyClassAAAAA &)) &operator== },
  {typeid(DummyClassBBBB), (bool (*)(const DummyClassBBBB &, const DummyClassBBBB &)) &operator== },
  {typeid(DummyClassCCC), (bool (*)(const DummyClassCCC &, const DummyClassCCC &)) &operator== },
  {typeid(DummyClassDDDDDDDDD), (bool (*)(const DummyClassDDDDDDDDD &, const DummyClassDDDDDDDDD &)) &operator== },
  {typeid(DummyClassEEEEEEE), (bool (*)(const DummyClassEEEEEEE &, const DummyClassEEEEEEE &)) &operator== },
  {typeid(DummyClassFFFFFFFFFF), (bool (*)(const DummyClassFFFFFFFFFF &, const DummyClassFFFFFFFFFF &)) &operator== }
};

// after formatting

const auto functionMap = std::map<std::type_index, void *>{{typeid(DummyClassAAAAA),
  (bool (*)(const DummyClassAAAAA &, const DummyClassAAAAA &)) &operator== },
  {typeid(DummyClassBBBB), (bool (*)(const DummyClassBBBB &, const DummyClassBBBB &)) &operator== },
    {typeid(DummyClassCCC), (bool (*)(const DummyClassCCC &, const DummyClassCCC &)) &operator== },
      {typeid(DummyClassDDDDDDDDD), (bool (*)(const DummyClassDDDDDDDDD &, const DummyClassDDDDDDDDD &)) &operator== },
        {typeid(DummyClassEEEEEEE), (bool (*)(const DummyClassEEEEEEE &, const DummyClassEEEEEEE &)) &operator== },
          {typeid(DummyClassFFFFFFFFFF),
            (bool (*)(const DummyClassFFFFFFFFFF &, const DummyClassFFFFFFFFFF &)) &operator== } };

Мой .clang-format файл:

UseTab: Never
IndentWidth: 2
BreakBeforeBraces: Allman
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AllowShortFunctionsOnASingleLine: false
ColumnLimit: 120
ContinuationIndentWidth: 2
ConstructorInitializerIndentWidth: 2
PointerAlignment: Right
DerivePointerAlignment: false
AlignAfterOpenBracket: DontAlign
AllowShortBlocksOnASingleLine: false
SpaceAfterTemplateKeyword: false
AlwaysBreakTemplateDeclarations: Yes
AlignTrailingComments: true
IndentCaseLabels: true
BreakBeforeBinaryOperators: NonAssignment
AllowAllParametersOfDeclarationOnNextLine: false

Я использую clang-format version 9.0.0 (tags/RELEASE_900/final) в Windows.

Единственное требование здесь - каждая пара в списке инициализации должна начинаться с новой строки, но в том же столбце. Я бы не хотел отключать clang-format для любого фрагмента кода, поэтому я действительно хотел бы решить эту проблему, настроив clang-format для получения правильного вывода.

Есть идеи, как это решить? Может быть, если нет способа добиться этого, не мог бы кто-нибудь предоставить доказательства этого?

Изменить - Решение

После добавления дополнительных фигурных скобок результат будет выглядеть так:

const std::map<std::type_index, void *> functionMap{
  {typeid(DummyClassAAAAA), ((bool (*)(const DummyClassAAAAA &, const DummyClassAAAAA &)) & operator==)},
  {typeid(DummyClassBBBB), ((bool (*)(const DummyClassBBBB &, const DummyClassBBBB &)) & operator==)},
  {typeid(DummyClassCCC), ((bool (*)(const DummyClassCCC &, const DummyClassCCC &)) & operator==)},
  {typeid(DummyClassDDDDDDDDD), ((bool (*)(const DummyClassDDDDDDDDD &, const DummyClassDDDDDDDDD &)) & operator==)},
  {typeid(DummyClassEEEEEEE), ((bool (*)(const DummyClassEEEEEEE &, const DummyClassEEEEEEE &)) & operator==)},
  {typeid(DummyClassFFFFFFFFFF), ((bool (*)(const DummyClassFFFFFFFFFF &, const DummyClassFFFFFFFFFF &)) & operator==)},
};

person János Benjamin Antal    schedule 08.12.2019    source источник
comment
Чтобы убедиться, что это вариант для вас, но добавление фигурных скобок вокруг значений приведет к правильному выравниванию. {typeid(DummyClassAAAAA), ((bool (*)(const DummyClassAAAAA &, const DummyClassAAAAA &)) &operator==) }   -  person t.niese    schedule 08.12.2019
comment
Спасибо за подсказку, помогает! Для полного решения необходимо добавить дополнительную запятую после последнего элемента. Если вы напишете это также в ответе, я буду рад принять это как ответ.   -  person János Benjamin Antal    schedule 08.12.2019


Ответы (1)


Я не могу сказать вам, почему clang-format выполняет такое форматирование в данном случае и следует ли рассматривать это как ошибку.

Но в таких ситуациях фигурные скобки могут помочь решить форматирование, поскольку они изменяют AST и, следовательно, применяемые правила, а также то, что используется в качестве ссылок для выравнивания.

Добавление фигурных скобок вокруг части значения исправит выравнивание элементов карты:

{typeid(DummyClassAAAAA),
       ((bool (*)(const DummyClassAAAAA &, const DummyClassAAAAA &)) &
        operator==)}

В зависимости от того, какое общее выравнивание вы хотите иметь в полном списке, вам необходимо добавить запятую после последнего элемента, например, переведите }; на новую строку.

person t.niese    schedule 08.12.2019