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