diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 41d19185d..4b805cdb0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -200,10 +200,10 @@ jobs: -Value "set(VCPKG_BUILD_TYPE release)","set(VCPKG_OSX_DEPLOYMENT_TARGET 10.15)" # NOTE: Avoids a libtorrent ABI issue. See https://github.com/arvidn/libtorrent/issues/4965 - - name: force AppleClang to compile libtorrent with C++14 + - name: force AppleClang to compile libtorrent with C++17 run: | (Get-Content -path ${{ env.RUNVCPKG_VCPKG_ROOT }}/ports/libtorrent/portfile.cmake).Replace( ` - '${FEATURE_OPTIONS}', '${FEATURE_OPTIONS} -DCMAKE_CXX_STANDARD=14') ` + '${FEATURE_OPTIONS}', '${FEATURE_OPTIONS} -DCMAKE_CXX_STANDARD=17') ` | Set-Content -Path ${{ env.RUNVCPKG_VCPKG_ROOT }}/ports/libtorrent/portfile.cmake - name: install dependencies via vcpkg diff --git a/.travis.yml b/.travis.yml index 11608019b..dfc3ccb9a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -129,7 +129,7 @@ install: cmake \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_CXX_STANDARD=14 \ + -DCMAKE_CXX_STANDARD=17 \ -Ddeprecated-functions=OFF \ -DOPENSSL_ROOT_DIR="$openssl_root_path" \ ./ @@ -145,7 +145,7 @@ install: cmake \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_CXX_STANDARD=14 \ + -DCMAKE_CXX_STANDARD=17 \ -Ddeprecated-functions=ON \ -DOPENSSL_ROOT_DIR="$openssl_root_path" \ ./ diff --git a/cmake/Modules/MacroQbtCommonConfig.cmake b/cmake/Modules/MacroQbtCommonConfig.cmake index 34276a82b..03114e704 100644 --- a/cmake/Modules/MacroQbtCommonConfig.cmake +++ b/cmake/Modules/MacroQbtCommonConfig.cmake @@ -20,22 +20,11 @@ macro(qbt_common_config) add_library(qbt_common_cfg INTERFACE) - # Full C++ 14 support is required + # Full C++ 17 support is required # See also https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html # for a breakdown of the features that CMake recognizes for each C++ standard target_compile_features(qbt_common_cfg INTERFACE - cxx_std_14 - cxx_aggregate_default_initializers - cxx_attribute_deprecated - cxx_binary_literals - cxx_contextual_conversions - cxx_decltype_auto - cxx_digit_separators - cxx_generic_lambdas - cxx_lambda_init_captures - cxx_relaxed_constexpr - cxx_return_type_deduction - cxx_variable_templates + cxx_std_17 ) set(QBT_PROJECT_VERSION "${qBittorrent_VERSION_MAJOR}.${qBittorrent_VERSION_MINOR}.${qBittorrent_VERSION_PATCH}") diff --git a/configure b/configure index 17ea5787c..ef41256c5 100755 --- a/configure +++ b/configure @@ -5564,18 +5564,18 @@ $as_echo "yes" >&6; } LIBS="$zlib_LIBS $LIBS" fi -# Check if already in >= C++14 mode because of the flags returned by one of the above packages +# Check if already in >= C++17 mode because of the flags returned by one of the above packages TMP_CXXFLAGS="$CXXFLAGS" CXXFLAGS="" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler defaults to C++14 or later mode" >&5 -$as_echo_n "checking if compiler defaults to C++14 or later mode... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler defaults to C++17 or later mode" >&5 +$as_echo_n "checking if compiler defaults to C++17 or later mode... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus #error "This is not a C++ compiler" - #elif __cplusplus < 201402L - #error "This is not a C++14 compiler" + #elif __cplusplus < 201703L + #error "This is not a C++17 compiler" #endif int main () @@ -5589,27 +5589,27 @@ _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - QBT_CXX14_FOUND="yes" + QBT_CXX17_FOUND="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - QBT_CXX14_FOUND="no" + QBT_CXX17_FOUND="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# In case of no, check if the compiler can support at least C++14 +# In case of no, check if the compiler can support at least C++17 # and if yes, enable it leaving a warning to the user -if test "x$QBT_CXX14_FOUND" = "xno"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports C++14" >&5 -$as_echo_n "checking if compiler supports C++14... " >&6; } - CXXFLAGS="-std=c++14" +if test "x$QBT_CXX17_FOUND" = "xno"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports C++17" >&5 +$as_echo_n "checking if compiler supports C++17... " >&6; } + CXXFLAGS="-std=c++17" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus #error "This is not a C++ compiler" - #elif __cplusplus < 201402L - #error "This is not a C++14 compiler" + #elif __cplusplus < 201703L + #error "This is not a C++17 compiler" #endif int main () @@ -5623,17 +5623,17 @@ _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if C++14 is disabled by the set compiler flags" >&5 -$as_echo_n "checking if C++14 is disabled by the set compiler flags... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if C++17 is disabled by the set compiler flags" >&5 +$as_echo_n "checking if C++17 is disabled by the set compiler flags... " >&6; } # prepend the flag so it won't override conflicting user defined flags - CXXFLAGS="-std=c++14 $TMP_CXXFLAGS" + CXXFLAGS="-std=c++17 $TMP_CXXFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus #error "This is not a C++ compiler" - #elif __cplusplus < 201402L - #error "This is not a C++14 compiler" + #elif __cplusplus < 201703L + #error "This is not a C++17 compiler" #endif int main () @@ -5647,19 +5647,19 @@ _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - QBT_ADD_CONFIG="$QBT_ADD_CONFIG c++14" - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C++14 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors." >&5 -$as_echo "$as_me: WARNING: C++14 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors." >&2;} + QBT_ADD_CONFIG="$QBT_ADD_CONFIG c++17" + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C++17 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors." >&5 +$as_echo "$as_me: WARNING: C++17 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors." >&2;} else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - as_fn_error $? "The compiler supports C++14 but the user or a dependency has explicitly enabled a lower mode." "$LINENO" 5 + as_fn_error $? "The compiler supports C++17 but the user or a dependency has explicitly enabled a lower mode." "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - as_fn_error $? "A compiler supporting C++14 is required." "$LINENO" 5 + as_fn_error $? "A compiler supporting C++17 is required." "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext @@ -7034,7 +7034,9 @@ $as_echo X/"$am_mf" | { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } @@ -8351,7 +8353,9 @@ $as_echo X/"$am_mf" | { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } diff --git a/configure.ac b/configure.ac index 324bbfce6..dacc72c0b 100644 --- a/configure.ac +++ b/configure.ac @@ -194,34 +194,34 @@ PKG_CHECK_MODULES(zlib, [CXXFLAGS="$zlib_CFLAGS $CXXFLAGS" LIBS="$zlib_LIBS $LIBS"]) -# Check if already in >= C++14 mode because of the flags returned by one of the above packages +# Check if already in >= C++17 mode because of the flags returned by one of the above packages TMP_CXXFLAGS="$CXXFLAGS" CXXFLAGS="" -AC_MSG_CHECKING([if compiler defaults to C++14 or later mode]) -AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()], +AC_MSG_CHECKING([if compiler defaults to C++17 or later mode]) +AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()], [AC_MSG_RESULT([yes]) - QBT_CXX14_FOUND="yes"], + QBT_CXX17_FOUND="yes"], [AC_MSG_RESULT([no]) - QBT_CXX14_FOUND="no"]) + QBT_CXX17_FOUND="no"]) -# In case of no, check if the compiler can support at least C++14 +# In case of no, check if the compiler can support at least C++17 # and if yes, enable it leaving a warning to the user -AS_IF([test "x$QBT_CXX14_FOUND" = "xno"], - [AC_MSG_CHECKING([if compiler supports C++14]) - CXXFLAGS="-std=c++14" - AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()], +AS_IF([test "x$QBT_CXX17_FOUND" = "xno"], + [AC_MSG_CHECKING([if compiler supports C++17]) + CXXFLAGS="-std=c++17" + AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()], [AC_MSG_RESULT([yes]) - AC_MSG_CHECKING([if C++14 is disabled by the set compiler flags]) + AC_MSG_CHECKING([if C++17 is disabled by the set compiler flags]) # prepend the flag so it won't override conflicting user defined flags - CXXFLAGS="-std=c++14 $TMP_CXXFLAGS" - AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()], + CXXFLAGS="-std=c++17 $TMP_CXXFLAGS" + AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()], [AC_MSG_RESULT([no]) - QBT_ADD_CONFIG="$QBT_ADD_CONFIG c++14" - AC_MSG_WARN([C++14 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors.])], + QBT_ADD_CONFIG="$QBT_ADD_CONFIG c++17" + AC_MSG_WARN([C++17 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors.])], [AC_MSG_RESULT([yes]) - AC_MSG_ERROR([The compiler supports C++14 but the user or a dependency has explicitly enabled a lower mode.])])], + AC_MSG_ERROR([The compiler supports C++17 but the user or a dependency has explicitly enabled a lower mode.])])], [AC_MSG_RESULT([no]) - AC_MSG_ERROR([A compiler supporting C++14 is required.])]) + AC_MSG_ERROR([A compiler supporting C++17 is required.])]) ]) CXXFLAGS="$TMP_CXXFLAGS" diff --git a/m4/qbittorrent.m4 b/m4/qbittorrent.m4 index daf8adc26..a8c200f45 100644 --- a/m4/qbittorrent.m4 +++ b/m4/qbittorrent.m4 @@ -37,15 +37,15 @@ AC_DEFUN([FIND_QTDBUS], HAVE_QTDBUS=[false]]) ]) -# DETECT_CPP14_PROGRAM() -# Detects if at least C++14 mode is enabled. +# DETECT_CPP17_PROGRAM() +# Detects if at least C++17 mode is enabled. # -------------------------------------- -AC_DEFUN([DETECT_CPP14_PROGRAM], +AC_DEFUN([DETECT_CPP17_PROGRAM], [AC_LANG_PROGRAM([[ #ifndef __cplusplus #error "This is not a C++ compiler" - #elif __cplusplus < 201402L - #error "This is not a C++14 compiler" + #elif __cplusplus < 201703L + #error "This is not a C++17 compiler" #endif]], [[]]) ]) diff --git a/src/base/algorithm.h b/src/base/algorithm.h index c26ef5620..bc192c112 100644 --- a/src/base/algorithm.h +++ b/src/base/algorithm.h @@ -32,9 +32,6 @@ namespace Algorithm { - template - using void_t = void; // replace this with std::void_t in C++17 - template struct HasMappedType : std::false_type @@ -42,7 +39,7 @@ namespace Algorithm }; template - struct HasMappedType> + struct HasMappedType> : std::true_type { }; diff --git a/src/base/bittorrent/common.h b/src/base/bittorrent/common.h index 6a12cfd92..60bd03ce6 100644 --- a/src/base/bittorrent/common.h +++ b/src/base/bittorrent/common.h @@ -30,5 +30,4 @@ #include -// TODO: Make it inline in C++17 -extern const QString QB_EXT; +inline const QString QB_EXT {QStringLiteral(".!qB")}; diff --git a/src/base/bittorrent/ltunderlyingtype.h b/src/base/bittorrent/ltunderlyingtype.h index 8df51fbfc..42df0aa43 100644 --- a/src/base/bittorrent/ltunderlyingtype.h +++ b/src/base/bittorrent/ltunderlyingtype.h @@ -30,9 +30,6 @@ #include -template -using void_t = void; // replace this with std::void_t in C++17 - template struct HasUnderlyingType : std::false_type @@ -40,7 +37,7 @@ struct HasUnderlyingType }; template -struct HasUnderlyingType> +struct HasUnderlyingType> : std::true_type { }; diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index ec8eda4f2..fdcf3ab7a 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -291,9 +291,8 @@ namespace LowerLimited lowerLimited(T limit, T ret) { return LowerLimited(limit, ret); } template - std::function clampValue(const T lower, const T upper) + auto clampValue(const T lower, const T upper) { - // TODO: change return type to `auto` when using C++17 return [lower, upper](const T value) -> T { if (value < lower) diff --git a/src/base/bittorrent/torrenthandleimpl.cpp b/src/base/bittorrent/torrenthandleimpl.cpp index e98a43b9e..b9dff5119 100644 --- a/src/base/bittorrent/torrenthandleimpl.cpp +++ b/src/base/bittorrent/torrenthandleimpl.cpp @@ -69,8 +69,6 @@ #include "session.h" #include "trackerentry.h" -const QString QB_EXT {QStringLiteral(".!qB")}; - using namespace BitTorrent; namespace diff --git a/src/base/indexrange.h b/src/base/indexrange.h index 395c79306..0960067a2 100644 --- a/src/base/indexrange.h +++ b/src/base/indexrange.h @@ -37,8 +37,7 @@ class IndexInterval public: using IndexType = Index; - // TODO: add constexpr when using C++17 - IndexInterval(const IndexType first, const IndexType last) + constexpr IndexInterval(const IndexType first, const IndexType last) : m_first {first} , m_last {last} { diff --git a/src/base/settingvalue.h b/src/base/settingvalue.h index 94a82b21e..46be9c1c1 100644 --- a/src/base/settingvalue.h +++ b/src/base/settingvalue.h @@ -48,7 +48,13 @@ public: T get(const T &defaultValue = {}) const { - return load(defaultValue); + if constexpr (std::is_enum_v) { + const auto value = SettingsStorage::instance()->loadValue(m_keyName, {}).toString(); + return Utils::String::toEnum(value, defaultValue); + } + else { + return SettingsStorage::instance()->loadValue(m_keyName, defaultValue).template value(); + } } operator T() const @@ -58,39 +64,14 @@ public: SettingValue &operator=(const T &value) { - store(value); + if constexpr (std::is_enum_v) + SettingsStorage::instance()->storeValue(m_keyName, Utils::String::fromEnum(value)); + else + SettingsStorage::instance()->storeValue(m_keyName, value); return *this; } private: - // regular load/store pair - template ::value, int> = 0> - U load(const U &defaultValue) const - { - return SettingsStorage::instance()->loadValue(m_keyName, defaultValue) - .template value(); - } - - template ::value, int> = 0> - void store(const U &value) - { - SettingsStorage::instance()->storeValue(m_keyName, value); - } - - // load/store pair for enum type, saves literal value of the enum constant - // TODO: merge the load/store functions with `if constexpr` in C++17 - template ::value, int> = 0> - U load(const U defaultValue) const - { - return Utils::String::toEnum(load(QString {}), defaultValue); - } - - template ::value, int> = 0> - void store(const U value) - { - store(Utils::String::fromEnum(value)); - } - const QString m_keyName; }; diff --git a/src/base/tristatebool.h b/src/base/tristatebool.h index 6c0a7aca8..eb794a4d4 100644 --- a/src/base/tristatebool.h +++ b/src/base/tristatebool.h @@ -42,7 +42,7 @@ public: *this = boolean ? True : False; } - TriStateBool &operator=(const TriStateBool &other) = default; // TODO: add constexpr when using C++17 + constexpr TriStateBool &operator=(const TriStateBool &other) = default; explicit constexpr operator signed char() const { diff --git a/src/base/utils/io.cpp b/src/base/utils/io.cpp index 51cfaaeb1..e25b5931f 100644 --- a/src/base/utils/io.cpp +++ b/src/base/utils/io.cpp @@ -60,18 +60,3 @@ Utils::IO::FileDeviceOutputIterator &Utils::IO::FileDeviceOutputIterator::operat } return *this; } - -Utils::IO::FileDeviceOutputIterator &Utils::IO::FileDeviceOutputIterator::operator*() -{ - return *this; -} - -Utils::IO::FileDeviceOutputIterator &Utils::IO::FileDeviceOutputIterator::operator++() -{ - return *this; -} - -Utils::IO::FileDeviceOutputIterator &Utils::IO::FileDeviceOutputIterator::operator++(int) -{ - return *this; -} diff --git a/src/base/utils/io.h b/src/base/utils/io.h index 0c1959e63..0937d59d3 100644 --- a/src/base/utils/io.h +++ b/src/base/utils/io.h @@ -49,10 +49,21 @@ namespace Utils // mimic std::ostream_iterator behavior FileDeviceOutputIterator &operator=(char c); - // TODO: make these `constexpr` in C++17 - FileDeviceOutputIterator &operator*(); - FileDeviceOutputIterator &operator++(); - FileDeviceOutputIterator &operator++(int); + + constexpr FileDeviceOutputIterator &operator*() + { + return *this; + } + + constexpr FileDeviceOutputIterator &operator++() + { + return *this; + } + + constexpr FileDeviceOutputIterator &operator++(int) + { + return *this; + } private: QFileDevice *m_device; diff --git a/src/base/utils/string.h b/src/base/utils/string.h index 72d75cf68..7a700bee2 100644 --- a/src/base/utils/string.h +++ b/src/base/utils/string.h @@ -73,20 +73,20 @@ namespace Utils QString join(const QVector &strings, const QString &separator); - template ::value, int> = 0> + template , int> = 0> QString fromEnum(const T &value) { - static_assert(std::is_same>::value, + static_assert(std::is_same_v>, "Enumeration underlying type has to be int."); const auto metaEnum = QMetaEnum::fromType(); return QString::fromLatin1(metaEnum.valueToKey(static_cast(value))); } - template ::value, int> = 0> + template , int> = 0> T toEnum(const QString &serializedValue, const T &defaultValue) { - static_assert(std::is_same>::value, + static_assert(std::is_same_v>, "Enumeration underlying type has to be int."); const auto metaEnum = QMetaEnum::fromType(); diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp index e70340246..7e7f82df0 100644 --- a/src/gui/advancedsettings.cpp +++ b/src/gui/advancedsettings.cpp @@ -715,12 +715,12 @@ void AdvancedSettings::addRow(const int row, const QString &text, T *widget) setCellWidget(row, PROPERTY, label); setCellWidget(row, VALUE, widget); - if (std::is_same::value) + if (std::is_same_v) connect(widget, SIGNAL(stateChanged(int)), this, SIGNAL(settingsChanged())); - else if (std::is_same::value) + else if (std::is_same_v) connect(widget, SIGNAL(valueChanged(int)), this, SIGNAL(settingsChanged())); - else if (std::is_same::value) + else if (std::is_same_v) connect(widget, SIGNAL(currentIndexChanged(int)), this, SIGNAL(settingsChanged())); - else if (std::is_same::value) + else if (std::is_same_v) connect(widget, SIGNAL(textChanged(QString)), this, SIGNAL(settingsChanged())); } diff --git a/winconf.pri b/winconf.pri index ca75c9cde..ce427349e 100644 --- a/winconf.pri +++ b/winconf.pri @@ -35,12 +35,15 @@ win32-g++* { DEFINES += _FILE_OFFSET_BITS=64 DEFINES += __USE_W32_SOCKETS + QMAKE_CXXFLAGS += -std=c++17 + RC_FILE = qbittorrent_mingw.rc LIBS += libadvapi32 libiphlpapi libole32 libpowrprof libshell32 libuser32 libwsock32 libws2_32 } else:win32-msvc* { CONFIG -= embed_manifest_exe + QMAKE_CXXFLAGS += /std:c++17 QMAKE_LFLAGS += "/MANIFEST:EMBED /MANIFESTINPUT:$$quote($${PWD}/src/qbittorrent.exe.manifest) /STACK:0x800000" RC_FILE = qbittorrent.rc