File indexing completed on 2024-04-28 05:26:46
0001 /* 0002 * SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #pragma once 0008 0009 #include <QElapsedTimer> 0010 #include <QJsonValue> 0011 #include <QScopeGuard> 0012 #include <QString> 0013 #include <functional> 0014 0015 class OneTimeAction : public QObject 0016 { 0017 public: 0018 // the int argument is only so the compile knows to tell the constructors apart 0019 OneTimeAction(int /*unnecessary*/, const std::function<bool()> &func, QObject *parent) 0020 : QObject(parent) 0021 , m_function(func) 0022 { 0023 } 0024 0025 OneTimeAction(const std::function<void()> &func, QObject *parent) 0026 : QObject(parent) 0027 , m_function([func] { 0028 func(); 0029 return true; 0030 }) 0031 { 0032 } 0033 0034 void trigger() 0035 { 0036 if (m_done) 0037 return; 0038 m_done = m_function(); 0039 deleteLater(); 0040 } 0041 0042 private: 0043 std::function<bool()> m_function; 0044 bool m_done = false; 0045 }; 0046 0047 template<typename T, typename Q, typename _UnaryOperation> 0048 static T kTransform(const Q &input, _UnaryOperation op) 0049 { 0050 T ret; 0051 ret.reserve(input.size()); 0052 for (const auto &v : input) { 0053 ret += op(v); 0054 } 0055 return ret; 0056 } 0057 0058 template<typename T, typename Q> 0059 static T kTransform(const Q &input) 0060 { 0061 T ret; 0062 ret.reserve(input.size()); 0063 for (const auto &v : input) { 0064 ret += v; 0065 } 0066 return ret; 0067 } 0068 0069 template<typename T, typename Q, typename _UnaryOperation> 0070 static T kAppend(const Q &input, _UnaryOperation op) 0071 { 0072 T ret; 0073 ret.reserve(input.size()); 0074 for (const auto &v : input) { 0075 ret.append(op(v)); 0076 } 0077 return ret; 0078 } 0079 0080 template<typename T, typename Q, typename _UnaryOperation> 0081 static T kFilter(const Q &input, _UnaryOperation op) 0082 { 0083 T ret; 0084 for (const auto &v : input) { 0085 if (op(v)) 0086 ret += v; 0087 } 0088 return ret; 0089 } 0090 0091 template<typename T, typename Q, typename _UnaryOperation> 0092 static void kFilterInPlace(Q &input, _UnaryOperation op) 0093 { 0094 for (auto it = input.begin(); it != input.end();) { 0095 if (op(*it)) 0096 ++it; 0097 else 0098 it = input.erase(it); 0099 } 0100 } 0101 0102 template<typename Q, typename W> 0103 static int kIndexOf(const Q &list, W func) 0104 { 0105 int i = 0; 0106 for (auto it = list.constBegin(), itEnd = list.constEnd(); it != itEnd; ++it) { 0107 if (func(*it)) 0108 return i; 0109 ++i; 0110 } 0111 return -1; 0112 } 0113 0114 template<typename Q, typename W> 0115 static bool kContains(const Q &list, W func) 0116 { 0117 return std::any_of(list.begin(), list.end(), func); 0118 } 0119 0120 template<typename Q, typename W> 0121 static bool kContainsValue(const Q &list, W value) 0122 { 0123 return std::find(list.begin(), list.end(), value) != list.end(); 0124 } 0125 0126 template<typename T> 0127 static QVector<T> kSetToVector(const QSet<T> &set) 0128 { 0129 QVector<T> ret; 0130 ret.reserve(set.size()); 0131 for (auto &x : set) 0132 ret.append(x); 0133 return ret; 0134 } 0135 template<typename T> 0136 static QList<T> kSetToList(const QSet<T> &set) 0137 { 0138 QList<T> ret; 0139 ret.reserve(set.size()); 0140 for (auto &x : set) 0141 ret.append(x); 0142 return ret; 0143 } 0144 template<typename T> 0145 static QSet<T> kToSet(const QList<T> &set) 0146 { 0147 return QSet<T>(set.begin(), set.end()); 0148 } 0149 0150 class ElapsedDebug : private QElapsedTimer 0151 { 0152 public: 0153 ElapsedDebug(const QString &name = QStringLiteral("<unnamed>")) 0154 : m_name(name) 0155 { 0156 start(); 0157 } 0158 ~ElapsedDebug() 0159 { 0160 qDebug("elapsed %s: %lld!", m_name.toUtf8().constData(), elapsed()); 0161 } 0162 void step(const QString &step) 0163 { 0164 qDebug("step %s(%s): %lld!", m_name.toUtf8().constData(), qPrintable(step), elapsed()); 0165 } 0166 0167 QString m_name; 0168 }; 0169 0170 inline void swap(QJsonValueRef v1, QJsonValueRef v2) 0171 { 0172 QJsonValue temp(v1); 0173 v1 = QJsonValue(v2); 0174 v2 = temp; 0175 } 0176 0177 template<typename T> 0178 class KeyValueRange 0179 { 0180 public: 0181 KeyValueRange(T &data) 0182 : m_data{data} 0183 { 0184 } 0185 0186 auto begin() 0187 { 0188 return m_data.keyValueBegin(); 0189 } 0190 0191 auto end() 0192 { 0193 return m_data.keyValueEnd(); 0194 } 0195 0196 private: 0197 T &m_data; 0198 };