File indexing completed on 2024-05-19 16:38:21

0001 /*
0002     SPDX-FileCopyrightText: 2015, 2016 Ivan Cukic <ivan.cukic(at)kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include <optional>
0008 
0009 namespace KActivities
0010 {
0011 namespace Stats
0012 {
0013 using namespace Terms;
0014 
0015 typedef ResultSet::const_iterator iterator;
0016 
0017 // Iterator
0018 
0019 class ResultSet_IteratorPrivate
0020 {
0021 public:
0022     ResultSet_IteratorPrivate(const ResultSet *resultSet, int currentRow = -1)
0023         : resultSet(resultSet)
0024         , currentRow(currentRow)
0025     {
0026         updateValue();
0027     }
0028 
0029     const ResultSet *resultSet;
0030     int currentRow;
0031     std::optional<ResultSet::Result> currentValue;
0032 
0033     inline void moveTo(int row)
0034     {
0035         if (row == currentRow)
0036             return;
0037         currentRow = row;
0038         updateValue();
0039     }
0040 
0041     inline void moveBy(int row)
0042     {
0043         moveTo(currentRow + row);
0044     }
0045 
0046     void updateValue()
0047     {
0048         if (!resultSet || !resultSet->d->query.seek(currentRow)) {
0049             currentValue.reset();
0050 
0051         } else {
0052             auto value = resultSet->d->currentResult();
0053             currentValue = std::move(value);
0054         }
0055     }
0056 
0057     friend void swap(ResultSet_IteratorPrivate &left, ResultSet_IteratorPrivate &right)
0058     {
0059         std::swap(left.resultSet, right.resultSet);
0060         std::swap(left.currentRow, right.currentRow);
0061         std::swap(left.currentValue, right.currentValue);
0062     }
0063 
0064     bool operator==(const ResultSet_IteratorPrivate &other) const
0065     {
0066         bool thisValid = currentValue.has_value();
0067         bool otherValid = other.currentValue.has_value();
0068 
0069         return
0070             // If one is valid, and the other is not,
0071             // they are not equal
0072             thisValid != otherValid ? false :
0073 
0074                                     // If both are invalid, they are equal
0075             !thisValid ? true
0076                        :
0077 
0078                        // Otherwise, really compare
0079             resultSet == other.resultSet && currentRow == other.currentRow;
0080     }
0081 
0082     bool isValid() const
0083     {
0084         return currentValue.has_value();
0085     }
0086 
0087     static bool sameSource(const ResultSet_IteratorPrivate &left, const ResultSet_IteratorPrivate &right)
0088     {
0089         return left.resultSet == right.resultSet && left.resultSet != nullptr;
0090     }
0091 };
0092 
0093 iterator::const_iterator(const ResultSet *resultSet, int currentRow)
0094     : d(new ResultSet_IteratorPrivate(resultSet, currentRow))
0095 {
0096 }
0097 
0098 iterator::const_iterator()
0099     : d(new ResultSet_IteratorPrivate(nullptr, -1))
0100 {
0101 }
0102 
0103 iterator::const_iterator(const const_iterator &source)
0104     : d(new ResultSet_IteratorPrivate(source.d->resultSet, source.d->currentRow))
0105 {
0106 }
0107 
0108 bool iterator::isSourceValid() const
0109 {
0110     return d->resultSet != nullptr;
0111 }
0112 
0113 iterator &iterator::operator=(const const_iterator &source)
0114 {
0115     const_iterator temp(source);
0116     swap(*d, *temp.d);
0117     return *this;
0118 }
0119 
0120 iterator::~const_iterator()
0121 {
0122     delete d;
0123 }
0124 
0125 iterator::reference iterator::operator*() const
0126 {
0127     return d->currentValue.value();
0128 }
0129 
0130 iterator::pointer iterator::operator->() const
0131 {
0132     return &d->currentValue.value();
0133 }
0134 
0135 // prefix
0136 iterator &iterator::operator++()
0137 {
0138     d->currentRow++;
0139     d->updateValue();
0140 
0141     return *this;
0142 }
0143 
0144 // postfix
0145 iterator iterator::operator++(int)
0146 {
0147     return const_iterator(d->resultSet, d->currentRow + 1);
0148 }
0149 
0150 // prefix
0151 iterator &iterator::operator--()
0152 {
0153     d->currentRow--;
0154     d->updateValue();
0155 
0156     return *this;
0157 }
0158 
0159 // postfix
0160 iterator iterator::operator--(int)
0161 {
0162     return const_iterator(d->resultSet, d->currentRow - 1);
0163 }
0164 
0165 iterator ResultSet::begin() const
0166 {
0167     return const_iterator(this, d->database ? 0 : -1);
0168 }
0169 
0170 iterator ResultSet::end() const
0171 {
0172     return const_iterator(this, -1);
0173 }
0174 
0175 iterator iterator::operator+(iterator::difference_type n) const
0176 {
0177     return const_iterator(d->resultSet, d->currentRow + n);
0178 }
0179 
0180 iterator &iterator::operator+=(iterator::difference_type n)
0181 {
0182     d->moveBy(n);
0183     return *this;
0184 }
0185 
0186 iterator iterator::operator-(iterator::difference_type n) const
0187 {
0188     return const_iterator(d->resultSet, d->currentRow - n);
0189 }
0190 
0191 iterator &iterator::operator-=(iterator::difference_type n)
0192 {
0193     d->moveBy(-n);
0194     return *this;
0195 }
0196 
0197 iterator::reference iterator::operator[](iterator::difference_type n) const
0198 {
0199     return *(*this + n);
0200 }
0201 
0202 // bool iterator::operator==(const const_iterator &right) const
0203 // {
0204 //     return *d == *right.d;
0205 // }
0206 //
0207 // bool iterator::operator!=(const const_iterator &right) const
0208 // {
0209 //     return !(*d == *right.d);
0210 // }
0211 
0212 bool operator==(const iterator &left, const iterator &right)
0213 {
0214     return *left.d == *right.d;
0215 }
0216 
0217 bool operator!=(const iterator &left, const iterator &right)
0218 {
0219     return !(*left.d == *right.d);
0220 }
0221 
0222 #define COMPARATOR_IMPL(OP)                                                                                                                                    \
0223     bool operator OP(const iterator &left, const iterator &right)                                                                                              \
0224     {                                                                                                                                                          \
0225         return ResultSet_IteratorPrivate::sameSource(*left.d, *right.d) ? left.d->currentRow OP right.d->currentRow : false;                                   \
0226     }
0227 
0228 COMPARATOR_IMPL(<)
0229 COMPARATOR_IMPL(>)
0230 COMPARATOR_IMPL(<=)
0231 COMPARATOR_IMPL(>=)
0232 
0233 #undef COMPARATOR_IMPL
0234 
0235 iterator::difference_type operator-(const iterator &left, const iterator &right)
0236 {
0237     return ResultSet_IteratorPrivate::sameSource(*left.d, *right.d) ? left.d->currentRow - right.d->currentRow : 0;
0238 }
0239 
0240 } // namespace Stats
0241 } // namespace KActivities