Browse Source

Replace template conditionals with C++20 `requires` clause

Related: https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-constraints.html

PR #19424.
adaptive-webui-19844
Chocobo1 1 year ago committed by GitHub
parent
commit
5c06d0aa75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      src/base/algorithm.h
  2. 4
      src/base/orderedset.h
  3. 10
      src/base/settingsstorage.h
  4. 6
      src/base/utils/string.h
  5. 4
      src/base/utils/version.h
  6. 14
      test/testalgorithm.cpp

16
src/base/algorithm.h

@ -1,5 +1,6 @@
/* /*
* Bittorrent Client using Qt and libtorrent. * Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2023 Mike Tzou (Chocobo1)
* Copyright (C) 2018 Vladimir Golovnev <glassez@yandex.ru> * Copyright (C) 2018 Vladimir Golovnev <glassez@yandex.ru>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -28,25 +29,16 @@
#pragma once #pragma once
#include <type_traits>
namespace Algorithm namespace Algorithm
{ {
template <typename T, typename = void>
struct HasMappedType
: std::false_type
{
};
template <typename T> template <typename T>
struct HasMappedType<T, std::void_t<typename T::mapped_type>> concept HasMappedType = requires
: std::true_type
{ {
typename T::mapped_type;
}; };
// To be used with associative array types, such as QMap, QHash and its variants // To be used with associative array types, such as QMap, QHash and its variants
template <typename T, typename BinaryPredicate template <HasMappedType T, typename BinaryPredicate>
, typename std::enable_if_t<HasMappedType<T>::value, int> = 0>
void removeIf(T &dict, BinaryPredicate &&p) void removeIf(T &dict, BinaryPredicate &&p)
{ {
auto it = dict.begin(); auto it = dict.begin();

4
src/base/orderedset.h

@ -29,9 +29,9 @@
#pragma once #pragma once
#include <concepts>
#include <functional> #include <functional>
#include <set> #include <set>
#include <type_traits>
#include "algorithm.h" #include "algorithm.h"
@ -70,8 +70,8 @@ public:
return BaseType::empty(); return BaseType::empty();
} }
template <typename std::enable_if_t<std::is_same_v<value_type, QString>, int> = 0>
QString join(const QString &separator) const QString join(const QString &separator) const
requires std::same_as<value_type, QString>
{ {
auto iter = BaseType::cbegin(); auto iter = BaseType::cbegin();
if (iter == BaseType::cend()) if (iter == BaseType::cend())

10
src/base/settingsstorage.h

@ -1,5 +1,6 @@
/* /*
* Bittorrent Client using Qt and libtorrent. * Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2023 Mike Tzou (Chocobo1)
* Copyright (C) 2016 Vladimir Golovnev <glassez@yandex.ru> * Copyright (C) 2016 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2014 sledgehammer999 <hammered999@gmail.com> * Copyright (C) 2014 sledgehammer999 <hammered999@gmail.com>
* *
@ -41,10 +42,7 @@
#include "utils/string.h" #include "utils/string.h"
template <typename T> template <typename T>
struct IsQFlags : std::false_type {}; concept IsQFlags = std::same_as<T, QFlags<typename T::enum_type>>;
template <typename T>
struct IsQFlags<QFlags<T>> : std::true_type {};
// There are 2 ways for class `T` provide serialization support into `SettingsStorage`: // There are 2 ways for class `T` provide serialization support into `SettingsStorage`:
// 1. If the `T` state is intended for users to edit (via a text editor), then // 1. If the `T` state is intended for users to edit (via a text editor), then
@ -76,7 +74,7 @@ public:
const auto value = loadValue<QString>(key); const auto value = loadValue<QString>(key);
return Utils::String::toEnum(value, defaultValue); return Utils::String::toEnum(value, defaultValue);
} }
else if constexpr (IsQFlags<T>::value) else if constexpr (IsQFlags<T>)
{ {
const typename T::Int value = loadValue(key, static_cast<typename T::Int>(defaultValue)); const typename T::Int value = loadValue(key, static_cast<typename T::Int>(defaultValue));
return T {value}; return T {value};
@ -101,7 +99,7 @@ public:
storeValueImpl(key, value.toString()); storeValueImpl(key, value.toString());
else if constexpr (std::is_enum_v<T>) else if constexpr (std::is_enum_v<T>)
storeValueImpl(key, Utils::String::fromEnum(value)); storeValueImpl(key, Utils::String::fromEnum(value));
else if constexpr (IsQFlags<T>::value) else if constexpr (IsQFlags<T>)
storeValueImpl(key, static_cast<typename T::Int>(value)); storeValueImpl(key, static_cast<typename T::Int>(value));
else else
storeValueImpl(key, QVariant::fromValue(value)); storeValueImpl(key, QVariant::fromValue(value));

6
src/base/utils/string.h

@ -67,8 +67,9 @@ namespace Utils::String
QString fromDouble(double n, int precision); QString fromDouble(double n, int precision);
template <typename T, typename std::enable_if_t<std::is_enum_v<T>, int> = 0> template <typename T>
QString fromEnum(const T &value) QString fromEnum(const T &value)
requires std::is_enum_v<T>
{ {
static_assert(std::is_same_v<int, typename std::underlying_type_t<T>>, static_assert(std::is_same_v<int, typename std::underlying_type_t<T>>,
"Enumeration underlying type has to be int."); "Enumeration underlying type has to be int.");
@ -77,8 +78,9 @@ namespace Utils::String
return QString::fromLatin1(metaEnum.valueToKey(static_cast<int>(value))); return QString::fromLatin1(metaEnum.valueToKey(static_cast<int>(value)));
} }
template <typename T, typename std::enable_if_t<std::is_enum_v<T>, int> = 0> template <typename T>
T toEnum(const QString &serializedValue, const T &defaultValue) T toEnum(const QString &serializedValue, const T &defaultValue)
requires std::is_enum_v<T>
{ {
static_assert(std::is_same_v<int, typename std::underlying_type_t<T>>, static_assert(std::is_same_v<int, typename std::underlying_type_t<T>>,
"Enumeration underlying type has to be int."); "Enumeration underlying type has to be int.");

4
src/base/utils/version.h

@ -55,9 +55,9 @@ namespace Utils
constexpr Version() = default; constexpr Version() = default;
template <typename ... Ts template <typename ... Ts>
, typename std::enable_if_t<std::conjunction_v<std::is_convertible<Ts, int>...>, int> = 0>
constexpr Version(Ts ... params) constexpr Version(Ts ... params)
requires std::conjunction_v<std::is_convertible<Ts, int>...>
: m_components {{params ...}} : m_components {{params ...}}
{ {
static_assert((sizeof...(Ts) <= N), "Too many parameters provided"); static_assert((sizeof...(Ts) <= N), "Too many parameters provided");

14
test/testalgorithm.cpp

@ -47,14 +47,14 @@ public:
private slots: private slots:
void testHasMappedType() const void testHasMappedType() const
{ {
QVERIFY(static_cast<bool>(Algorithm::HasMappedType<std::map<bool, bool>>::value)); static_assert(Algorithm::HasMappedType<std::map<bool, bool>>);
QVERIFY(static_cast<bool>(Algorithm::HasMappedType<std::unordered_map<bool, bool>>::value)); static_assert(Algorithm::HasMappedType<std::unordered_map<bool, bool>>);
QVERIFY(static_cast<bool>(Algorithm::HasMappedType<QHash<bool, bool>>::value)); static_assert(Algorithm::HasMappedType<QHash<bool, bool>>);
QVERIFY(static_cast<bool>(Algorithm::HasMappedType<QMap<bool, bool>>::value)); static_assert(Algorithm::HasMappedType<QMap<bool, bool>>);
QVERIFY(!static_cast<bool>(Algorithm::HasMappedType<std::set<bool>>::value)); static_assert(!Algorithm::HasMappedType<std::set<bool>>);
QVERIFY(!static_cast<bool>(Algorithm::HasMappedType<std::unordered_set<bool>>::value)); static_assert(!Algorithm::HasMappedType<std::unordered_set<bool>>);
QVERIFY(!static_cast<bool>(Algorithm::HasMappedType<QSet<bool>>::value)); static_assert(!Algorithm::HasMappedType<QSet<bool>>);
} }
void testMappedTypeRemoveIf() const void testMappedTypeRemoveIf() const

Loading…
Cancel
Save