Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 09:04:36

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 
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     ResultStore stores indexed results. Results can be added and retrieved
0017     either individually batched in a QList. Retriveing results and checking
0018     which indexes are in the store can be done either by iterating or by random
0019     access. In addition results can be removed from the front of the store,
0020     either individually or in batches.
0021 */
0022 
0023 namespace QtPrivate {
0024 
0025 class ResultItem
0026 {
0027 public:
0028     ResultItem(const void *_result, int _count) : m_count(_count), result(_result) { } // construct with vector of results
0029     ResultItem(const void *_result) : m_count(0), result(_result) { } // construct with 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;          // result is either a pointer to a result or to a vector of results,
0035     const void *result; // if count is 0 it's a result, otherwise it's a vector.
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     // ### Qt 7: 'virtual' isn't required, can be removed, along with renaming
0112     // the class to ResultStore and changing the members below to be private.
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;     // The index where the next results(s) will be inserted.
0125     int resultCount;     // The number of consecutive results stored, starting at index 0.
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)) // reject if already present
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)) // reject if already present
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()) // reject if results are empty
0178             return -1;
0179 
0180         if (containsValidResultItem(index)) // reject if already present
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         // reject if results are empty, and nothing is filtered away
0190         if ((m_filterMode == false || results->size() == totalCount) && results->empty())
0191             return -1;
0192 
0193         if (containsValidResultItem(index)) // reject if already present
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)) // reject if already present
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)) // reject if already present
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 } // namespace QtPrivate
0232 
0233 Q_DECLARE_TYPEINFO(QtPrivate::ResultItem, Q_PRIMITIVE_TYPE);
0234 
0235 
0236 QT_END_NAMESPACE
0237 
0238 #endif