Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-08 08:49:26

0001 // Copyright (C) 2020 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 // Qt-Security score:significant reason:default
0004 
0005 #ifndef QTCORE_RESULTSTORE_H
0006 #define QTCORE_RESULTSTORE_H
0007 
0008 #include <QtCore/qmap.h>
0009 
0010 #include <utility>
0011 
0012 QT_REQUIRE_CONFIG(future);
0013 
0014 QT_BEGIN_NAMESPACE
0015 
0016 /*
0017     ResultStore stores indexed results. Results can be added and retrieved
0018     either individually batched in a QList. Retriveing results and checking
0019     which indexes are in the store can be done either by iterating or by random
0020     access. In addition results can be removed from the front of the store,
0021     either individually or in batches.
0022 */
0023 
0024 namespace QtPrivate {
0025 
0026 class ResultItem
0027 {
0028 public:
0029     ResultItem(const void *_result, int _count) : m_count(_count), result(_result) { } // construct with vector of results
0030     ResultItem(const void *_result) : m_count(0), result(_result) { } // construct with result
0031     ResultItem() : m_count(0), result(nullptr) { }
0032     bool isValid() const { return result != nullptr; }
0033     bool isVector() const { return m_count != 0; }
0034     int count() const { return (m_count == 0) ?  1 : m_count; }
0035     int m_count;          // result is either a pointer to a result or to a vector of results,
0036     const void *result; // if count is 0 it's a result, otherwise it's a vector.
0037 };
0038 
0039 class Q_CORE_EXPORT ResultIteratorBase
0040 {
0041 public:
0042     ResultIteratorBase();
0043     ResultIteratorBase(QMap<int, ResultItem>::const_iterator _mapIterator, int _vectorIndex = 0);
0044     int vectorIndex() const;
0045     int resultIndex() const;
0046 
0047     ResultIteratorBase operator++();
0048     int batchSize() const;
0049     void batchedAdvance();
0050 #if QT_CORE_REMOVED_SINCE(6, 8)
0051     bool operator==(const ResultIteratorBase &other) const;
0052     bool operator!=(const ResultIteratorBase &other) const;
0053 #endif
0054     bool isVector() const;
0055     bool canIncrementVectorIndex() const;
0056     bool isValid() const;
0057 
0058 private:
0059     friend bool comparesEqual(const ResultIteratorBase &lhs,
0060                               const ResultIteratorBase &rhs)
0061     {
0062         return (lhs.mapIterator == rhs.mapIterator && lhs.m_vectorIndex == rhs.m_vectorIndex);
0063     }
0064     Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(ResultIteratorBase)
0065 protected:
0066     QMap<int, ResultItem>::const_iterator mapIterator;
0067     int m_vectorIndex;
0068 public:
0069     template <typename T>
0070     const T &value() const
0071     {
0072         return *pointer<T>();
0073     }
0074 
0075     template<typename T>
0076     T &value()
0077     {
0078         return *pointer<T>();
0079     }
0080 
0081     template <typename T>
0082     T *pointer()
0083     {
0084         const T *p = std::as_const(*this).pointer<T>();
0085         return const_cast<T *>(p);
0086     }
0087 
0088     template <typename T>
0089     const T *pointer() const
0090     {
0091         if (mapIterator.value().isVector())
0092             return &(reinterpret_cast<const QList<T> *>(mapIterator.value().result)->at(m_vectorIndex));
0093         else
0094             return reinterpret_cast<const T *>(mapIterator.value().result);
0095     }
0096 };
0097 
0098 class Q_CORE_EXPORT ResultStoreBase final
0099 {
0100 public:
0101     ResultStoreBase();
0102     void setFilterMode(bool enable);
0103     bool filterMode() const;
0104     int addResult(int index, const void *result);
0105     int addResults(int index, const void *results, int vectorSize, int logicalCount);
0106     ResultIteratorBase begin() const;
0107     ResultIteratorBase end() const;
0108     bool hasNextResult() const;
0109     ResultIteratorBase resultAt(int index) const;
0110     bool contains(int index) const;
0111     int count() const;
0112     // ### Qt 7: 'virtual' isn't required, can be removed, along with renaming
0113     // the class to ResultStore and changing the members below to be private.
0114     QT_WARNING_PUSH
0115 #if defined(Q_CC_CLANG)
0116 #  if __has_warning("-Wunnecessary-virtual-specifier")
0117     QT_WARNING_DISABLE_CLANG("-Wunnecessary-virtual-specifier")
0118 #  endif
0119 #endif
0120     virtual ~ResultStoreBase();
0121     QT_WARNING_POP
0122 
0123 protected:
0124     int insertResultItem(int index, ResultItem &resultItem);
0125     void insertResultItemIfValid(int index, ResultItem &resultItem);
0126     bool containsValidResultItem(int index) const;
0127     void syncPendingResults();
0128     void syncResultCount();
0129     int updateInsertIndex(int index, int _count);
0130 
0131     QMap<int, ResultItem> m_results;
0132     int insertIndex;     // The index where the next results(s) will be inserted.
0133     int resultCount;     // The number of consecutive results stored, starting at index 0.
0134 
0135     bool m_filterMode;
0136     QMap<int, ResultItem> pendingResults;
0137     int filteredResults;
0138 
0139     template <typename T>
0140     static void clear(QMap<int, ResultItem> &store)
0141     {
0142         QMap<int, ResultItem>::const_iterator mapIterator = store.constBegin();
0143         while (mapIterator != store.constEnd()) {
0144             if (mapIterator.value().isVector())
0145                 delete reinterpret_cast<const QList<T> *>(mapIterator.value().result);
0146             else
0147                 delete reinterpret_cast<const T *>(mapIterator.value().result);
0148             ++mapIterator;
0149         }
0150         store.clear();
0151     }
0152 
0153 public:
0154     template <typename T, typename...Args>
0155     int emplaceResult(int index, Args&&...args)
0156     {
0157         if (containsValidResultItem(index)) // reject if already present
0158             return -1;
0159         return addResult(index, static_cast<void *>(new T(std::forward<Args>(args)...)));
0160     }
0161 
0162     template <typename T>
0163     int addResult(int index, const T *result)
0164     {
0165         if (containsValidResultItem(index)) // reject if already present
0166             return -1;
0167 
0168         if (result == nullptr)
0169             return addResult(index, static_cast<void *>(nullptr));
0170 
0171         return addResult(index, static_cast<void *>(new T(*result)));
0172     }
0173 
0174     template <typename T>
0175     int moveResult(int index, T &&result)
0176     {
0177         static_assert(!std::is_reference_v<T>, "trying to move from an lvalue!");
0178 
0179         return emplaceResult<std::remove_cv_t<T>>(index, std::forward<T>(result));
0180     }
0181 
0182     template<typename T>
0183     int addResults(int index, const QList<T> *results)
0184     {
0185         if (results->empty()) // reject if results are empty
0186             return -1;
0187 
0188         if (containsValidResultItem(index)) // reject if already present
0189             return -1;
0190 
0191         return addResults(index, new QList<T>(*results), results->size(), results->size());
0192     }
0193 
0194     template<typename T>
0195     int addResults(int index, const QList<T> *results, int totalCount)
0196     {
0197         // reject if results are empty, and nothing is filtered away
0198         if ((m_filterMode == false || results->size() == totalCount) && results->empty())
0199             return -1;
0200 
0201         if (containsValidResultItem(index)) // reject if already present
0202             return -1;
0203 
0204         if (m_filterMode == true && results->size() != totalCount && 0 == results->size())
0205             return addResults(index, nullptr, 0, totalCount);
0206 
0207         return addResults(index, new QList<T>(*results), results->size(), totalCount);
0208     }
0209 
0210     int addCanceledResult(int index)
0211     {
0212         if (containsValidResultItem(index)) // reject if already present
0213             return -1;
0214 
0215         return addResult(index, static_cast<void *>(nullptr));
0216     }
0217 
0218     template <typename T>
0219     int addCanceledResults(int index, int _count)
0220     {
0221         if (containsValidResultItem(index)) // reject if already present
0222             return -1;
0223 
0224         QList<T> empty;
0225         return addResults(index, &empty, _count);
0226     }
0227 
0228     template <typename T>
0229     void clear()
0230     {
0231         ResultStoreBase::clear<T>(m_results);
0232         resultCount = 0;
0233         insertIndex = 0;
0234         ResultStoreBase::clear<T>(pendingResults);
0235         filteredResults = 0;
0236     }
0237 };
0238 
0239 } // namespace QtPrivate
0240 
0241 Q_DECLARE_TYPEINFO(QtPrivate::ResultItem, Q_PRIMITIVE_TYPE);
0242 
0243 
0244 QT_END_NAMESPACE
0245 
0246 #endif