Merge pull request #14005 from Chocobo1/cpp17

Bump project requirement to C++17
This commit is contained in:
Mike Tzou 2021-01-01 12:49:16 +08:00 committed by GitHub
commit cfb55d9d77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 113 additions and 148 deletions

View file

@ -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

View file

@ -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" \
./

View file

@ -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}")

56
configure vendored
View file

@ -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; }

View file

@ -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"

View file

@ -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]],
[[]])
])

View file

@ -152,7 +152,7 @@ bool QtLocalPeer::isClient()
#endif
if (!res)
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection()));
connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection);
return false;
}

View file

@ -32,9 +32,6 @@
namespace Algorithm
{
template <typename ...>
using void_t = void; // replace this with std::void_t in C++17
template <typename T, typename = void>
struct HasMappedType
: std::false_type
@ -42,7 +39,7 @@ namespace Algorithm
};
template <typename T>
struct HasMappedType<T, void_t<typename T::mapped_type>>
struct HasMappedType<T, std::void_t<typename T::mapped_type>>
: std::true_type
{
};

View file

@ -30,5 +30,4 @@
#include <QString>
// TODO: Make it inline in C++17
extern const QString QB_EXT;
inline const QString QB_EXT {QStringLiteral(".!qB")};

View file

@ -30,9 +30,6 @@
#include <type_traits>
template <typename ...>
using void_t = void; // replace this with std::void_t in C++17
template <typename T, typename = void>
struct HasUnderlyingType
: std::false_type
@ -40,7 +37,7 @@ struct HasUnderlyingType
};
template <typename T>
struct HasUnderlyingType<T, void_t<typename T::underlying_type>>
struct HasUnderlyingType<T, std::void_t<typename T::underlying_type>>
: std::true_type
{
};

View file

@ -291,9 +291,8 @@ namespace
LowerLimited<T> lowerLimited(T limit, T ret) { return LowerLimited<T>(limit, ret); }
template <typename T>
std::function<T (const T&)> 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)

View file

@ -69,8 +69,6 @@
#include "session.h"
#include "trackerentry.h"
const QString QB_EXT {QStringLiteral(".!qB")};
using namespace BitTorrent;
namespace

View file

@ -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}
{

View file

@ -48,7 +48,13 @@ public:
T get(const T &defaultValue = {}) const
{
return load(defaultValue);
if constexpr (std::is_enum_v<T>) {
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<T>();
}
}
operator T() const
@ -58,39 +64,14 @@ public:
SettingValue<T> &operator=(const T &value)
{
store(value);
if constexpr (std::is_enum_v<T>)
SettingsStorage::instance()->storeValue(m_keyName, Utils::String::fromEnum(value));
else
SettingsStorage::instance()->storeValue(m_keyName, value);
return *this;
}
private:
// regular load/store pair
template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0>
U load(const U &defaultValue) const
{
return SettingsStorage::instance()->loadValue(m_keyName, defaultValue)
.template value<U>();
}
template <typename U, typename std::enable_if_t<!std::is_enum<U>::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 <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0>
U load(const U defaultValue) const
{
return Utils::String::toEnum(load(QString {}), defaultValue);
}
template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0>
void store(const U value)
{
store(Utils::String::fromEnum(value));
}
const QString m_keyName;
};

View file

@ -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
{

View file

@ -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;
}

View file

@ -40,19 +40,36 @@ namespace Utils
{
// A wrapper class that satisfy LegacyOutputIterator requirement
class FileDeviceOutputIterator
: public std::iterator<std::output_iterator_tag, void, void, void, void>
{
public:
// std::iterator_traits
using iterator_category = std::output_iterator_tag;
using difference_type = void;
using value_type = void;
using pointer = void;
using reference = void;
explicit FileDeviceOutputIterator(QFileDevice &device, const int bufferSize = (4 * 1024));
FileDeviceOutputIterator(const FileDeviceOutputIterator &other) = default;
~FileDeviceOutputIterator();
// 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;

View file

@ -73,20 +73,20 @@ namespace Utils
QString join(const QVector<QStringRef> &strings, const QString &separator);
template <typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
template <typename T, typename std::enable_if_t<std::is_enum_v<T>, int> = 0>
QString fromEnum(const T &value)
{
static_assert(std::is_same<int, typename std::underlying_type_t<T>>::value,
static_assert(std::is_same_v<int, typename std::underlying_type_t<T>>,
"Enumeration underlying type has to be int.");
const auto metaEnum = QMetaEnum::fromType<T>();
return QString::fromLatin1(metaEnum.valueToKey(static_cast<int>(value)));
}
template <typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
template <typename T, typename std::enable_if_t<std::is_enum_v<T>, int> = 0>
T toEnum(const QString &serializedValue, const T &defaultValue)
{
static_assert(std::is_same<int, typename std::underlying_type_t<T>>::value,
static_assert(std::is_same_v<int, typename std::underlying_type_t<T>>,
"Enumeration underlying type has to be int.");
const auto metaEnum = QMetaEnum::fromType<T>();

View file

@ -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<T, QCheckBox>::value)
connect(widget, SIGNAL(stateChanged(int)), this, SIGNAL(settingsChanged()));
else if (std::is_same<T, QSpinBox>::value)
connect(widget, SIGNAL(valueChanged(int)), this, SIGNAL(settingsChanged()));
else if (std::is_same<T, QComboBox>::value)
connect(widget, SIGNAL(currentIndexChanged(int)), this, SIGNAL(settingsChanged()));
else if (std::is_same<T, QLineEdit>::value)
connect(widget, SIGNAL(textChanged(QString)), this, SIGNAL(settingsChanged()));
if constexpr (std::is_same_v<T, QCheckBox>)
connect(widget, &QCheckBox::stateChanged, this, &AdvancedSettings::settingsChanged);
else if constexpr (std::is_same_v<T, QSpinBox>)
connect(widget, qOverload<int>(&QSpinBox::valueChanged), this, &AdvancedSettings::settingsChanged);
else if constexpr (std::is_same_v<T, QComboBox>)
connect(widget, qOverload<int>(&QComboBox::currentIndexChanged), this, &AdvancedSettings::settingsChanged);
else if constexpr (std::is_same_v<T, QLineEdit>)
connect(widget, &QLineEdit::textChanged, this, &AdvancedSettings::settingsChanged);
}

View file

@ -4,10 +4,7 @@ DEFINES += BOOST_ASIO_DISABLE_CONNECTEX
DEFINES += BOOST_EXCEPTION_DISABLE
DEFINES += TORRENT_USE_LIBCRYPTO
# TODO: remove the following define as it is not used since OpenSSL >= 1.1
DEFINES += TORRENT_USE_OPENSSL
# TODO: remove the following define as it is not used since libtorrent >= 1.2
DEFINES += TORRENT_DISABLE_RESOLVE_COUNTRIES
DEFINES += NTDDI_VERSION=0x06010000
DEFINES += _WIN32_WINNT=0x0601
@ -35,12 +32,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