Skip to content

Commit

Permalink
Upgrade to C++20 (#7554)
Browse files Browse the repository at this point in the history
* Compile in C++20 mode

* Fix implicit lambda captures of `this` by `[=]`

Those implicit captures were deprecated in C++20

* Silence MSVC atomic std::shared_ptr warning

Unfortunately std::atomic<std::shared_ptr> (P0718R2) is not supported by
GCC until GCC 12 and still is not supported by Clang or Apple Clang, so
it looks like we will continue using std::atomic_load for the time being

* Use C++20 in RemoteVstPlugin

* Simplification

* Add comment

* Fix bitwise operations between different enumeration types

* Revert "Fix bitwise operations between different enumeration types"

This reverts commit d45792c.

* Use a helper function to combine keys and modifiers

* Remove AnalyzeTemporaryDtors from .clang-tidy

AnalyzeTemporaryDtors was deprecated in clang-tidy 16 and fully removed
in clang-tidy 18

* Use C++20 in .clang-format

* Use bitwise OR

Prevents issues if any enum flags in `args` have bits in common
  • Loading branch information
messmerd authored Nov 23, 2024
1 parent 72b30b1 commit c21a7cd
Show file tree
Hide file tree
Showing 23 changed files with 109 additions and 73 deletions.
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
# Language
Language: Cpp
Standard: Cpp11 # Cpp14 and Cpp17 are not supported by clang 11
Standard: c++20

# Indentation
TabWidth: 4
Expand Down
1 change: 0 additions & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ Checks: >
readability-simplify-boolean-expr
WarningsAsErrors: ''
HeaderFilterRegex: '' # don't show errors from headers
AnalyzeTemporaryDtors: false
FormatStyle: none
User: user
CheckOptions:
Expand Down
4 changes: 4 additions & 0 deletions cmake/modules/ErrorFlags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ elseif(MSVC)
"/WX" # Treat warnings as errors
)
endif()

# Silence deprecation warnings for the std::atomic_...<std::shared_ptr> family of functions.
# TODO: Remove once C++20's std::atomic<std::shared_ptr> is fully supported.
add_compile_definitions("_SILENCE_CXX20_OLD_SHARED_PTR_ATOMIC_SUPPORT_DEPRECATION_WARNING")
endif()

# Add the flags to the whole directory tree. We use the third-party flags for
Expand Down
27 changes: 27 additions & 0 deletions include/DeprecationHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@
#ifndef LMMS_DEPRECATIONHELPER_H
#define LMMS_DEPRECATIONHELPER_H

#include <type_traits>

#include <QFontMetrics>
#include <QKeySequence>
#include <QWheelEvent>

namespace lmms
Expand Down Expand Up @@ -64,6 +67,30 @@ inline QPoint position(QWheelEvent *wheelEvent)
#endif
}


namespace detail
{

template<typename T>
inline constexpr bool IsKeyOrModifier = std::is_same_v<T, Qt::Key>
|| std::is_same_v<T, Qt::Modifier> || std::is_same_v<T, Qt::KeyboardModifier>;

} // namespace detail


/**
* @brief Combines Qt key and modifier arguments together,
* replacing `A | B` which was deprecated in C++20
* due to the enums being different types. (P1120R0)
* @param args Any number of Qt::Key, Qt::Modifier, or Qt::KeyboardModifier
* @return The combination of the given keys/modifiers as an int
*/
template<typename... Args, std::enable_if_t<(detail::IsKeyOrModifier<Args> && ...), bool> = true>
constexpr int combine(Args... args)
{
return (0 | ... | static_cast<int>(args));
}

} // namespace lmms

#endif // LMMS_DEPRECATIONHELPER_H
4 changes: 2 additions & 2 deletions plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
SET(CMAKE_DEBUG_POSTFIX "")

# Enable C++17
SET(CMAKE_CXX_STANDARD 17)
# Enable C++20
SET(CMAKE_CXX_STANDARD 20)

IF(LMMS_BUILD_APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
Expand Down
1 change: 0 additions & 1 deletion plugins/SpectrumAnalyzer/SaControlsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,6 @@ SaControlsDialog::SaControlsDialog(SaControls *controls, SaProcessor *processor)
m_waterfall = new SaWaterfallView(controls, processor, this);
display_splitter->addWidget(m_waterfall);
m_waterfall->setVisible(m_controls->m_waterfallModel.value());
connect(&controls->m_waterfallModel, &BoolModel::dataChanged, [=] {m_waterfall->updateVisibility();});
}


Expand Down
1 change: 1 addition & 0 deletions plugins/SpectrumAnalyzer/SaWaterfallView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ SaWaterfallView::SaWaterfallView(SaControls *controls, SaProcessor *processor, Q
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

connect(getGUI()->mainWindow(), SIGNAL(periodicUpdate()), this, SLOT(periodicUpdate()));
connect(&controls->m_waterfallModel, &BoolModel::dataChanged, this, &SaWaterfallView::updateVisibility);

m_displayTop = 1;
m_displayBottom = height() -2;
Expand Down
2 changes: 1 addition & 1 deletion plugins/Vibed/NineButtonSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ NineButtonSelector::NineButtonSelector(std::array<QPixmap, 18> onOffIcons, int d
m_buttons[i]->setActiveGraphic(onOffIcons[i * 2]);
m_buttons[i]->setInactiveGraphic(onOffIcons[(i * 2) + 1]);
m_buttons[i]->setChecked(false);
connect(m_buttons[i].get(), &PixmapButton::clicked, this, [=](){ this->buttonClicked(i); });
connect(m_buttons[i].get(), &PixmapButton::clicked, this, [=, this](){ buttonClicked(i); });
}

m_lastBtn = m_buttons[defaultButton].get();
Expand Down
4 changes: 2 additions & 2 deletions plugins/VstBase/RemoteVstPlugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ endif()

project(RemoteVstPlugin
LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)

include(CheckCXXPreprocessor)
include(CheckCXXSourceCompiles)
Expand Down Expand Up @@ -73,7 +73,7 @@ if(MSVC)
endif()

if(IS_MINGW)
SET(CMAKE_REQUIRED_FLAGS "-std=c++17")
SET(CMAKE_REQUIRED_FLAGS "-std=c++20")
endif()

if(LMMS_BUILD_WIN32)
Expand Down
2 changes: 1 addition & 1 deletion src/3rdparty/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ ADD_SUBDIRECTORY(weakjack)
add_library(ringbuffer OBJECT
ringbuffer/src/lib/ringbuffer.cpp
)
target_compile_features(ringbuffer PUBLIC cxx_std_17)
target_compile_features(ringbuffer PUBLIC cxx_std_20)
target_include_directories(ringbuffer PUBLIC
ringbuffer/include
"${CMAKE_CURRENT_BINARY_DIR}"
Expand Down
2 changes: 1 addition & 1 deletion src/3rdparty/hiir/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
add_library(hiir INTERFACE)
target_include_directories(hiir INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_features(hiir INTERFACE cxx_std_17)
target_compile_features(hiir INTERFACE cxx_std_20)
4 changes: 2 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ SET(CMAKE_AUTOMOC ON)
SET(CMAKE_AUTOUIC ON)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

# Enable C++17
SET(CMAKE_CXX_STANDARD 17)
# Enable C++20
SET(CMAKE_CXX_STANDARD 20)

IF(LMMS_BUILD_APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
Expand Down
14 changes: 8 additions & 6 deletions src/gui/ControllerRackView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,22 @@
*
*/

#include "ControllerRackView.h"

#include <QApplication>
#include <QAction>
#include <QPushButton>
#include <QScrollArea>
#include <QMessageBox>
#include <QVBoxLayout>

#include "Song.h"
#include "ControllerView.h"
#include "DeprecationHelper.h"
#include "embed.h"
#include "GuiApplication.h"
#include "MainWindow.h"
#include "ControllerRackView.h"
#include "ControllerView.h"
#include "LfoController.h"
#include "MainWindow.h"
#include "Song.h"
#include "SubWindow.h"

namespace lmms::gui
Expand Down Expand Up @@ -167,13 +169,13 @@ void ControllerRackView::addController(Controller* controller)
connect(controllerView, &ControllerView::removedController, this, &ControllerRackView::deleteController, Qt::QueuedConnection);

auto moveUpAction = new QAction(controllerView);
moveUpAction->setShortcut(Qt::Key_Up | Qt::AltModifier);
moveUpAction->setShortcut(combine(Qt::Key_Up, Qt::AltModifier));
moveUpAction->setShortcutContext(Qt::WidgetShortcut);
connect(moveUpAction, &QAction::triggered, controllerView, &ControllerView::moveUp);
controllerView->addAction(moveUpAction);

auto moveDownAction = new QAction(controllerView);
moveDownAction->setShortcut(Qt::Key_Down | Qt::AltModifier);
moveDownAction->setShortcut(combine(Qt::Key_Down, Qt::AltModifier));
moveDownAction->setShortcutContext(Qt::WidgetShortcut);
connect(moveDownAction, &QAction::triggered, controllerView, &ControllerView::moveDown);
controllerView->addAction(moveDownAction);
Expand Down
8 changes: 5 additions & 3 deletions src/gui/EffectRackView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
*
*/

#include "EffectRackView.h"

#include <QApplication>
#include <QAction>
#include <QPushButton>
#include <QScrollArea>
#include <QVBoxLayout>

#include "EffectRackView.h"
#include "DeprecationHelper.h"
#include "EffectSelectDialog.h"
#include "EffectView.h"
#include "GroupBox.h"
Expand Down Expand Up @@ -176,13 +178,13 @@ void EffectRackView::update()
connect(view, &EffectView::deletedPlugin, this, &EffectRackView::deletePlugin, Qt::QueuedConnection);

QAction* moveUpAction = new QAction(view);
moveUpAction->setShortcut(Qt::Key_Up | Qt::AltModifier);
moveUpAction->setShortcut(combine(Qt::Key_Up, Qt::AltModifier));
moveUpAction->setShortcutContext(Qt::WidgetShortcut);
connect(moveUpAction, &QAction::triggered, view, &EffectView::moveUp);
view->addAction(moveUpAction);

QAction* moveDownAction = new QAction(view);
moveDownAction->setShortcut(Qt::Key_Down | Qt::AltModifier);
moveDownAction->setShortcut(combine(Qt::Key_Down, Qt::AltModifier));
moveDownAction->setShortcutContext(Qt::WidgetShortcut);
connect(moveDownAction, &QAction::triggered, view, &EffectView::moveDown);
view->addAction(moveDownAction);
Expand Down
8 changes: 4 additions & 4 deletions src/gui/FileBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,15 +635,15 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e )

contextMenu.addAction(
tr( "Send to active instrument-track" ),
[=]{ sendToActiveInstrumentTrack(file); }
[=, this]{ sendToActiveInstrumentTrack(file); }
);

contextMenu.addSeparator();

contextMenu.addAction(
QIcon(embed::getIconPixmap("folder")),
tr("Open containing folder"),
[=]{ openContainingFolder(file); }
[=, this]{ openContainingFolder(file); }
);

auto songEditorHeader = new QAction(tr("Song Editor"), nullptr);
Expand Down Expand Up @@ -676,14 +676,14 @@ QList<QAction*> FileBrowserTreeWidget::getContextActions(FileItem* file, bool so

auto toInstrument = new QAction(instrumentAction + tr(" (%2Enter)").arg(shortcutMod), nullptr);
connect(toInstrument, &QAction::triggered,
[=]{ openInNewInstrumentTrack(file, songEditor); });
[=, this]{ openInNewInstrumentTrack(file, songEditor); });
result.append(toInstrument);

if (songEditor && fileIsSample)
{
auto toSampleTrack = new QAction(tr("Send to new sample track (Shift + Enter)"), nullptr);
connect(toSampleTrack, &QAction::triggered,
[=]{ openInNewSampleTrack(file); });
[=, this]{ openInNewSampleTrack(file); });
result.append(toSampleTrack);
}

Expand Down
35 changes: 18 additions & 17 deletions src/gui/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "AboutDialog.h"
#include "AutomationEditor.h"
#include "ControllerRackView.h"
#include "DeprecationHelper.h"
#include "embed.h"
#include "Engine.h"
#include "ExportProjectDialog.h"
Expand Down Expand Up @@ -293,11 +294,11 @@ void MainWindow::finalize()
project_menu->addAction( embed::getIconPixmap( "project_save" ),
tr( "Save &As..." ),
this, SLOT(saveProjectAs()),
Qt::CTRL + Qt::SHIFT + Qt::Key_S );
combine(Qt::CTRL, Qt::SHIFT, Qt::Key_S));
project_menu->addAction( embed::getIconPixmap( "project_save" ),
tr( "Save as New &Version" ),
this, SLOT(saveProjectAsNewVersion()),
Qt::CTRL + Qt::ALT + Qt::Key_S );
combine(Qt::CTRL, Qt::ALT, Qt::Key_S));

project_menu->addAction( embed::getIconPixmap( "project_save" ),
tr( "Save as default template" ),
Expand All @@ -312,23 +313,23 @@ void MainWindow::finalize()
tr( "E&xport..." ),
this,
SLOT(onExportProject()),
Qt::CTRL + Qt::Key_E );
combine(Qt::CTRL, Qt::Key_E));
project_menu->addAction( embed::getIconPixmap( "project_export" ),
tr( "E&xport Tracks..." ),
this,
SLOT(onExportProjectTracks()),
Qt::CTRL + Qt::SHIFT + Qt::Key_E );
combine(Qt::CTRL, Qt::SHIFT, Qt::Key_E));

project_menu->addAction( embed::getIconPixmap( "midi_file" ),
tr( "Export &MIDI..." ),
this,
SLOT(onExportProjectMidi()),
Qt::CTRL + Qt::Key_M );
combine(Qt::CTRL, Qt::Key_M));

project_menu->addSeparator();
project_menu->addAction( embed::getIconPixmap( "exit" ), tr( "&Quit" ),
qApp, SLOT(closeAllWindows()),
Qt::CTRL + Qt::Key_Q );
combine(Qt::CTRL, Qt::Key_Q));

auto edit_menu = new QMenu(this);
menuBar()->addMenu( edit_menu )->setText( tr( "&Edit" ) );
Expand All @@ -341,13 +342,13 @@ void MainWindow::finalize()
this, SLOT(redo()),
QKeySequence::Redo );
// Ensure that both (Ctrl+Y) and (Ctrl+Shift+Z) activate redo shortcut regardless of OS defaults
if (QKeySequence(QKeySequence::Redo) != QKeySequence(Qt::CTRL + Qt::Key_Y))
if (QKeySequence(QKeySequence::Redo) != QKeySequence(combine(Qt::CTRL, Qt::Key_Y)))
{
new QShortcut( QKeySequence( Qt::CTRL + Qt::Key_Y ), this, SLOT(redo()));
new QShortcut(QKeySequence(combine(Qt::CTRL, Qt::Key_Y)), this, SLOT(redo()));
}
if (QKeySequence(QKeySequence::Redo) != QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z ))
if (QKeySequence(QKeySequence::Redo) != QKeySequence(combine(Qt::CTRL, Qt::SHIFT, Qt::Key_Z)))
{
new QShortcut( QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_Z ), this, SLOT(redo()));
new QShortcut(QKeySequence(combine(Qt::CTRL, Qt::SHIFT, Qt::Key_Z)), this, SLOT(redo()));
}

edit_menu->addSeparator();
Expand Down Expand Up @@ -446,31 +447,31 @@ void MainWindow::finalize()
// window-toolbar
auto song_editor_window = new ToolButton(embed::getIconPixmap("songeditor"), tr("Song Editor") + " (Ctrl+1)", this,
SLOT(toggleSongEditorWin()), m_toolBar);
song_editor_window->setShortcut( Qt::CTRL + Qt::Key_1 );
song_editor_window->setShortcut(combine(Qt::CTRL, Qt::Key_1));

auto pattern_editor_window = new ToolButton(embed::getIconPixmap("pattern_track_btn"),
tr("Pattern Editor") + " (Ctrl+2)", this, SLOT(togglePatternEditorWin()), m_toolBar);
pattern_editor_window->setShortcut(Qt::CTRL + Qt::Key_2);
pattern_editor_window->setShortcut(combine(Qt::CTRL, Qt::Key_2));

auto piano_roll_window = new ToolButton(
embed::getIconPixmap("piano"), tr("Piano Roll") + " (Ctrl+3)", this, SLOT(togglePianoRollWin()), m_toolBar);
piano_roll_window->setShortcut( Qt::CTRL + Qt::Key_3 );
piano_roll_window->setShortcut(combine(Qt::CTRL, Qt::Key_3));

auto automation_editor_window = new ToolButton(embed::getIconPixmap("automation"),
tr("Automation Editor") + " (Ctrl+4)", this, SLOT(toggleAutomationEditorWin()), m_toolBar);
automation_editor_window->setShortcut( Qt::CTRL + Qt::Key_4 );
automation_editor_window->setShortcut(combine(Qt::CTRL, Qt::Key_4));

auto mixer_window = new ToolButton(
embed::getIconPixmap("mixer"), tr("Mixer") + " (Ctrl+5)", this, SLOT(toggleMixerWin()), m_toolBar);
mixer_window->setShortcut( Qt::CTRL + Qt::Key_5 );
mixer_window->setShortcut(combine(Qt::CTRL, Qt::Key_5));

auto controllers_window = new ToolButton(embed::getIconPixmap("controller"),
tr("Show/hide controller rack") + " (Ctrl+6)", this, SLOT(toggleControllerRack()), m_toolBar);
controllers_window->setShortcut( Qt::CTRL + Qt::Key_6 );
controllers_window->setShortcut(combine(Qt::CTRL, Qt::Key_6));

auto project_notes_window = new ToolButton(embed::getIconPixmap("project_notes"),
tr("Show/hide project notes") + " (Ctrl+7)", this, SLOT(toggleProjectNotesWin()), m_toolBar);
project_notes_window->setShortcut( Qt::CTRL + Qt::Key_7 );
project_notes_window->setShortcut(combine(Qt::CTRL, Qt::Key_7));

m_toolBarLayout->addWidget( song_editor_window, 1, 1 );
m_toolBarLayout->addWidget( pattern_editor_window, 1, 2 );
Expand Down
Loading

0 comments on commit c21a7cd

Please sign in to comment.