File indexing completed on 2025-09-16 09:04:36
0001
0002
0003
0004 #ifndef QTCORE_RESULTSTORE_H
0005 #define QTCORE_RESULTSTORE_H
0006
0007 #include <QtCore/qmap.h>
0008
0009 #include <utility>
0010
0011 QT_REQUIRE_CONFIG(future);
0012
0013 QT_BEGIN_NAMESPACE
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 namespace QtPrivate {
0024
0025 class ResultItem
0026 {
0027 public:
0028 ResultItem(const void *_result, int _count) : m_count(_count), result(_result) { }
0029 ResultItem(const void *_result) : m_count(0), result(_result) { }
0030 ResultItem() : m_count(0), result(nullptr) { }
0031 bool isValid() const { return result != nullptr; }
0032 bool isVector() const { return m_count != 0; }
0033 int count() const { return (m_count == 0) ? 1 : m_count; }
0034 int m_count;
0035 const void *result;
0036 };
0037
0038 class Q_CORE_EXPORT ResultIteratorBase
0039 {
0040 public:
0041 ResultIteratorBase();
0042 ResultIteratorBase(QMap<int, ResultItem>::const_iterator _mapIterator, int _vectorIndex = 0);
0043 int vectorIndex() const;
0044 int resultIndex() const;
0045
0046 ResultIteratorBase operator++();
0047 int batchSize() const;
0048 void batchedAdvance();
0049 #if QT_CORE_REMOVED_SINCE(6, 8)
0050 bool operator==(const ResultIteratorBase &other) const;
0051 bool operator!=(const ResultIteratorBase &other) const;
0052 #endif
0053 bool isVector() const;
0054 bool canIncrementVectorIndex() const;
0055 bool isValid() const;
0056
0057 private:
0058 friend bool comparesEqual(const ResultIteratorBase &lhs,
0059 const ResultIteratorBase &rhs)
0060 {
0061 return (lhs.mapIterator == rhs.mapIterator && lhs.m_vectorIndex == rhs.m_vectorIndex);
0062 }
0063 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(ResultIteratorBase)
0064 protected:
0065 QMap<int, ResultItem>::const_iterator mapIterator;
0066 int m_vectorIndex;
0067 public:
0068 template <typename T>
0069 const T &value() const
0070 {
0071 return *pointer<T>();
0072 }
0073
0074 template<typename T>
0075 T &value()
0076 {
0077 return *pointer<T>();
0078 }
0079
0080 template <typename T>
0081 T *pointer()
0082 {
0083 const T *p = std::as_const(*this).pointer<T>();
0084 return const_cast<T *>(p);
0085 }
0086
0087 template <typename T>
0088 const T *pointer() const
0089 {
0090 if (mapIterator.value().isVector())
0091 return &(reinterpret_cast<const QList<T> *>(mapIterator.value().result)->at(m_vectorIndex));
0092 else
0093 return reinterpret_cast<const T *>(mapIterator.value().result);
0094 }
0095 };
0096
0097 class Q_CORE_EXPORT ResultStoreBase final
0098 {
0099 public:
0100 ResultStoreBase();
0101 void setFilterMode(bool enable);
0102 bool filterMode() const;
0103 int addResult(int index, const void *result);
0104 int addResults(int index, const void *results, int vectorSize, int logicalCount);
0105 ResultIteratorBase begin() const;
0106 ResultIteratorBase end() const;
0107 bool hasNextResult() const;
0108 ResultIteratorBase resultAt(int index) const;
0109 bool contains(int index) const;
0110 int count() const;
0111
0112
0113 virtual ~ResultStoreBase();
0114
0115 protected:
0116 int insertResultItem(int index, ResultItem &resultItem);
0117 void insertResultItemIfValid(int index, ResultItem &resultItem);
0118 bool containsValidResultItem(int index) const;
0119 void syncPendingResults();
0120 void syncResultCount();
0121 int updateInsertIndex(int index, int _count);
0122
0123 QMap<int, ResultItem> m_results;
0124 int insertIndex;
0125 int resultCount;
0126
0127 bool m_filterMode;
0128 QMap<int, ResultItem> pendingResults;
0129 int filteredResults;
0130
0131 template <typename T>
0132 static void clear(QMap<int, ResultItem> &store)
0133 {
0134 QMap<int, ResultItem>::const_iterator mapIterator = store.constBegin();
0135 while (mapIterator != store.constEnd()) {
0136 if (mapIterator.value().isVector())
0137 delete reinterpret_cast<const QList<T> *>(mapIterator.value().result);
0138 else
0139 delete reinterpret_cast<const T *>(mapIterator.value().result);
0140 ++mapIterator;
0141 }
0142 store.clear();
0143 }
0144
0145 public:
0146 template <typename T, typename...Args>
0147 int emplaceResult(int index, Args&&...args)
0148 {
0149 if (containsValidResultItem(index))
0150 return -1;
0151 return addResult(index, static_cast<void *>(new T(std::forward<Args>(args)...)));
0152 }
0153
0154 template <typename T>
0155 int addResult(int index, const T *result)
0156 {
0157 if (containsValidResultItem(index))
0158 return -1;
0159
0160 if (result == nullptr)
0161 return addResult(index, static_cast<void *>(nullptr));
0162
0163 return addResult(index, static_cast<void *>(new T(*result)));
0164 }
0165
0166 template <typename T>
0167 int moveResult(int index, T &&result)
0168 {
0169 static_assert(!std::is_reference_v<T>, "trying to move from an lvalue!");
0170
0171 return emplaceResult<std::remove_cv_t<T>>(index, std::forward<T>(result));
0172 }
0173
0174 template<typename T>
0175 int addResults(int index, const QList<T> *results)
0176 {
0177 if (results->empty())
0178 return -1;
0179
0180 if (containsValidResultItem(index))
0181 return -1;
0182
0183 return addResults(index, new QList<T>(*results), results->size(), results->size());
0184 }
0185
0186 template<typename T>
0187 int addResults(int index, const QList<T> *results, int totalCount)
0188 {
0189
0190 if ((m_filterMode == false || results->size() == totalCount) && results->empty())
0191 return -1;
0192
0193 if (containsValidResultItem(index))
0194 return -1;
0195
0196 if (m_filterMode == true && results->size() != totalCount && 0 == results->size())
0197 return addResults(index, nullptr, 0, totalCount);
0198
0199 return addResults(index, new QList<T>(*results), results->size(), totalCount);
0200 }
0201
0202 int addCanceledResult(int index)
0203 {
0204 if (containsValidResultItem(index))
0205 return -1;
0206
0207 return addResult(index, static_cast<void *>(nullptr));
0208 }
0209
0210 template <typename T>
0211 int addCanceledResults(int index, int _count)
0212 {
0213 if (containsValidResultItem(index))
0214 return -1;
0215
0216 QList<T> empty;
0217 return addResults(index, &empty, _count);
0218 }
0219
0220 template <typename T>
0221 void clear()
0222 {
0223 ResultStoreBase::clear<T>(m_results);
0224 resultCount = 0;
0225 insertIndex = 0;
0226 ResultStoreBase::clear<T>(pendingResults);
0227 filteredResults = 0;
0228 }
0229 };
0230
0231 }
0232
0233 Q_DECLARE_TYPEINFO(QtPrivate::ResultItem, Q_PRIMITIVE_TYPE);
0234
0235
0236 QT_END_NAMESPACE
0237
0238 #endif