Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/inc/queryiter.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#pragma once
21
22
#include "queryparam.hxx"
23
#include "mtvelements.hxx"
24
#include "types.hxx"
25
#include "lookupsearchmode.hxx"
26
27
struct ScComplexRefData;
28
class ScSortedRangeCache;
29
30
/*
31
Query-related iterators. There is one template class ScQueryCellIteratorBase
32
that implements most of the shared functionality, specific parts are done
33
by specializing the templates and then subclassing as the actual class to use.
34
A template is used for maximum performance, as that allows fast code specializing,
35
inlining, etc.
36
There are two template arguments:
37
* ScQueryCellIteratorAccess specifies how cells are accessed:
38
  + Direct - direct access to cells using mdds.
39
  + SortedCache - for accessing unsorted cells in a sorted way using ScSortedRangeCache.
40
* ScQueryCellIteratorType specifies the type of the query operation:
41
  + Generic - the generic lookup, used e.g. by VLOOKUP.
42
  + CountIf - faster implementation for COUNTIF(S).
43
44
Specific data should be in specific templated base classes, otherwise adding data
45
members would mean specializing the entire ScQueryCellIteratorBase. Some specific
46
functionality may also be implemented in the base classes or depending on the template
47
parameter.
48
*/
49
50
// Data and functionality for accessing cells in a specific way.
51
// Needs specialization, see ScQueryCellIteratorAccess::Direct for what is needed.
52
template< ScQueryCellIteratorAccess accessType >
53
class ScQueryCellIteratorAccessSpecific
54
{
55
};
56
57
// The implementation using linear direct mdds access.
58
template<>
59
class ScQueryCellIteratorAccessSpecific< ScQueryCellIteratorAccess::Direct >
60
{
61
protected:
62
    ScQueryCellIteratorAccessSpecific( ScDocument& rDocument, ScInterpreterContext& rContext,
63
        const ScQueryParam& rParam, bool bReverseSearch );
64
    // Initialize position for new column.
65
    void InitPos();
66
    // Increase position (next row).
67
    void IncPos();
68
    // Next mdds block. If access is not direct/linear, then
69
    // should call IncPos().
70
    void IncBlock();
71
72
    // Decrease position (prev row).
73
    void DecPos();
74
    // Prev mdds block. If access is not direct/linear, then
75
    // should call DecPos().
76
    void DecBlock();
77
78
    // These members needs to be available already in the base class.
79
    typedef sc::CellStoreType::const_position_type PositionType;
80
    PositionType maCurPos;
81
    ScQueryParam    maParam;
82
    ScDocument&     rDoc;
83
    ScInterpreterContext& mrContext;
84
    bool            mbReverseSearch;
85
    SCTAB           nTab;
86
    SCCOL           nCol;
87
    SCROW           nRow;
88
89
    class NonEmptyCellIndexer;
90
    typedef std::pair<ScRefCellValue, SCCOLROW> BinarySearchCellType;
91
    static NonEmptyCellIndexer MakeBinarySearchIndexer(const sc::CellStoreType* pCells,
92
        SCCOLROW nStartRow, SCCOLROW nEndRow);
93
};
94
95
// The implementation using ScSortedRangeCache, which allows sorted iteration
96
// of unsorted cells.
97
template<>
98
class ScQueryCellIteratorAccessSpecific< ScQueryCellIteratorAccess::SortedCache >
99
{
100
public:
101
    void SetSortedRangeCache( const ScSortedRangeCache& cache );
102
    template<bool fast>
103
    bool IncPosImpl();
104
protected:
105
    ScQueryCellIteratorAccessSpecific( ScDocument& rDocument, ScInterpreterContext& rContext,
106
        const ScQueryParam& rParam, bool bReverseSearch );
107
    void InitPosStart(bool bNewSearchFunction, sal_uInt8 nSortedBinarySearch = 0x00);
108
    void InitPosFinish( SCROW beforeRow, SCROW lastRow, bool bFirstMatch );
109
    void InitPosColFinish( SCCOL beforeCol, SCCOL lastCol, bool bFirstMatch );
110
0
    void IncPos() { IncPosImpl<false>(); }
111
0
    bool IncPosFast() { return IncPosImpl<true>(); }
112
0
    void IncBlock() { IncPos(); } // Cannot skip entire block, not linear.
113
114
    // Initialize for backward search. (no need for SortedCache)
115
0
    static void DecPos() {};
116
0
    static void DecBlock() {};
117
118
    // These members needs to be available already in the base class.
119
    typedef sc::CellStoreType::const_position_type PositionType;
120
    PositionType maCurPos;
121
    ScQueryParam    maParam;
122
    ScDocument&     rDoc;
123
    ScInterpreterContext& mrContext;
124
    bool            mbReverseSearch;
125
    SCTAB           nTab;
126
    SCCOL           nCol;
127
    SCROW           nRow;
128
    const ScColumn* pColumn; // matching nCol, set by InitPos()
129
130
    const ScSortedRangeCache* sortedCache;
131
    size_t sortedCachePos;
132
    size_t sortedCachePosLast;
133
134
    class SortedCacheIndexer;
135
    typedef std::pair<ScRefCellValue, SCCOLROW> BinarySearchCellType;
136
    SortedCacheIndexer MakeBinarySearchIndexer(const sc::CellStoreType* pCells,
137
        SCCOLROW nStartRow, SCCOLROW nEndRow);
138
};
139
140
// Data and functionality for specific types of query.
141
template< ScQueryCellIteratorType iteratorType >
142
class ScQueryCellIteratorTypeSpecific
143
{
144
protected:
145
    bool HandleItemFound(); // not implemented, needs specialization
146
};
147
148
// Shared code for query-based iterators. The main class.
149
template< ScQueryCellIteratorAccess accessType, ScQueryCellIteratorType queryType >
150
class ScQueryCellIteratorBase
151
    : public ScQueryCellIteratorAccessSpecific< accessType >
152
    , public ScQueryCellIteratorTypeSpecific< queryType >
153
{
154
    typedef ScQueryCellIteratorAccessSpecific< accessType > AccessBase;
155
    typedef ScQueryCellIteratorTypeSpecific< queryType > TypeBase;
156
protected:
157
    enum StopOnMismatchBits
158
    {
159
        nStopOnMismatchDisabled = 0x00,
160
        nStopOnMismatchEnabled  = 0x01,
161
        nStopOnMismatchOccurred  = 0x02,
162
        nStopOnMismatchExecuted = nStopOnMismatchEnabled | nStopOnMismatchOccurred
163
    };
164
165
    enum TestEqualConditionBits
166
    {
167
        nTestEqualConditionDisabled = 0x00,
168
        nTestEqualConditionEnabled  = 0x01,
169
        nTestEqualConditionMatched  = 0x02,
170
        nTestEqualConditionFulfilled = nTestEqualConditionEnabled | nTestEqualConditionMatched
171
    };
172
173
    enum SortedBinarySearchBits
174
    {
175
        nBinarySearchDisabled = 0x00,
176
        nSearchbAscd = 0x01,
177
        nSearchbDesc = 0x02,
178
    };
179
180
    sal_uInt8            nStopOnMismatch;
181
    sal_uInt8            nTestEqualCondition;
182
    sal_uInt8            nSortedBinarySearch;
183
    bool            bAdvanceQuery;
184
    bool            bIgnoreMismatchOnLeadingStrings;
185
    sal_uInt16      nSearchOpCode;
186
    SCCOL           nBestFitCol;
187
    SCROW           nBestFitRow;
188
189
    // Make base members directly visible here (templated bases need 'this->').
190
    using AccessBase::maCurPos;
191
    using AccessBase::maParam;
192
    using AccessBase::rDoc;
193
    using AccessBase::mrContext;
194
    using AccessBase::mbReverseSearch;
195
    using AccessBase::nTab;
196
    using AccessBase::nCol;
197
    using AccessBase::nRow;
198
    using AccessBase::IncPos;
199
    using AccessBase::IncBlock;
200
    using AccessBase::DecPos;
201
    using AccessBase::DecBlock;
202
    using typename AccessBase::BinarySearchCellType;
203
    using AccessBase::MakeBinarySearchIndexer;
204
    using TypeBase::HandleItemFound;
205
206
    void InitPos();
207
208
    // The actual query function. It will call HandleItemFound() for any matching type
209
    // and return if HandleItemFound() returns true.
210
    void PerformQuery();
211
212
    /* Only works if no regular expression is involved, only searches for rows in one column or
213
       only searches for cols in one row, and only the first query entry is considered with simple
214
       conditions SC_LESS,SC_LESS_EQUAL, SC_EQUAL (sorted ascending) or SC_GREATER,SC_GREATER_EQUAL
215
       (sorted descending). It delivers a starting point set to nRow/nCol, i.e. the last row/col that
216
       either matches the searched for value, or the last row/col that matches the condition.
217
       Continue with e.g. GetThis() and GetNext() afterwards. Returns false if the searched for value
218
       is not in the search range or if the range is not properly sorted, with nRow/nCol in that case
219
       set to the first row or after the last row. In that case use GetFirst().
220
    */
221
    bool BinarySearch( SCCOLROW col_row, bool forEqual = false );
222
223
                    /** If set, iterator stops on first non-matching cell
224
                        content. May be used in SC_LESS_EQUAL queries where a
225
                        cell range is assumed to be sorted; stops on first
226
                        value being greater than the queried value and
227
                        GetFirst()/GetNext() return NULL. StoppedOnMismatch()
228
                        returns true then.
229
                        However, the iterator's conditions are not set to end
230
                        all queries, GetCol() and GetRow() return values for
231
                        the non-matching cell, further GetNext() calls may be
232
                        executed. */
233
    void            SetStopOnMismatch( bool bVal )
234
53
                        {
235
53
                            nStopOnMismatch = sal::static_int_cast<sal_uInt8>(bVal ? nStopOnMismatchEnabled :
236
53
                                nStopOnMismatchDisabled);
237
53
                        }
ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)0>::SetStopOnMismatch(bool)
Line
Count
Source
234
53
                        {
235
53
                            nStopOnMismatch = sal::static_int_cast<sal_uInt8>(bVal ? nStopOnMismatchEnabled :
236
53
                                nStopOnMismatchDisabled);
237
53
                        }
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)0>::SetStopOnMismatch(bool)
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)1>::SetStopOnMismatch(bool)
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)1>::SetStopOnMismatch(bool)
238
    bool            StoppedOnMismatch() const
239
0
                        { return nStopOnMismatch == nStopOnMismatchExecuted; }
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)0>::StoppedOnMismatch() const
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)0>::StoppedOnMismatch() const
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)1>::StoppedOnMismatch() const
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)1>::StoppedOnMismatch() const
240
241
                    /** If set, an additional test for SC_EQUAL condition is
242
                        executed in ScTable::ValidQuery() if SC_LESS_EQUAL or
243
                        SC_GREATER_EQUAL conditions are to be tested. May be
244
                        used where a cell range is assumed to be sorted to stop
245
                        if an equal match is found. */
246
    void            SetTestEqualCondition( bool bVal )
247
90
                        {
248
90
                            nTestEqualCondition = sal::static_int_cast<sal_uInt8>(bVal ?
249
53
                                nTestEqualConditionEnabled :
250
90
                                nTestEqualConditionDisabled);
251
90
                        }
ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)0>::SetTestEqualCondition(bool)
Line
Count
Source
247
90
                        {
248
90
                            nTestEqualCondition = sal::static_int_cast<sal_uInt8>(bVal ?
249
53
                                nTestEqualConditionEnabled :
250
90
                                nTestEqualConditionDisabled);
251
90
                        }
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)0>::SetTestEqualCondition(bool)
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)1>::SetTestEqualCondition(bool)
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)1>::SetTestEqualCondition(bool)
252
    bool            IsEqualConditionFulfilled() const
253
129
                        { return nTestEqualCondition == nTestEqualConditionFulfilled; }
ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)0>::IsEqualConditionFulfilled() const
Line
Count
Source
253
129
                        { return nTestEqualCondition == nTestEqualConditionFulfilled; }
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)0>::IsEqualConditionFulfilled() const
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)1>::IsEqualConditionFulfilled() const
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)1>::IsEqualConditionFulfilled() const
254
255
    void            HandleBestFitItemFound(SCCOL nBFitCol, SCROW nBFitRow)
256
0
                        {
257
0
                            nBestFitCol = nBFitCol;
258
0
                            nBestFitRow = nBFitRow;
259
0
                        }
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)0>::HandleBestFitItemFound(short, int)
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)0>::HandleBestFitItemFound(short, int)
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)1>::HandleBestFitItemFound(short, int)
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)1>::HandleBestFitItemFound(short, int)
260
public:
261
                    ScQueryCellIteratorBase(ScDocument& rDocument, ScInterpreterContext& rContext, SCTAB nTable,
262
                                            const ScQueryParam& aParam, bool bMod, bool bReverse);
263
                                        // when !bMod, the QueryParam has to be filled
264
                                        // (bIsString)
265
266
                    // increments all Entry.nField, if column
267
                    // changes, for ScInterpreter ScHLookup()
268
    void            SetAdvanceQueryParamEntryField( bool bVal )
269
5.78k
                        { bAdvanceQuery = bVal; }
ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)0>::SetAdvanceQueryParamEntryField(bool)
Line
Count
Source
269
5.47k
                        { bAdvanceQuery = bVal; }
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)0>::SetAdvanceQueryParamEntryField(bool)
ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)1>::SetAdvanceQueryParamEntryField(bool)
Line
Count
Source
269
310
                        { bAdvanceQuery = bVal; }
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)1>::SetAdvanceQueryParamEntryField(bool)
270
    void            AdvanceQueryParamEntryField();
271
    void            AdvanceQueryParamEntryFieldForBinarySearch();
272
273
    void            SetSortedBinarySearchMode( LookupSearchMode nSearchMode )
274
208
                        {
275
208
                            nSortedBinarySearch =
276
208
                                nSearchMode == LookupSearchMode::BinaryAscending
277
208
                                ? nSearchbAscd
278
208
                                : (nSearchMode == LookupSearchMode::BinaryDescending
279
208
                                   ? nSearchbDesc : nBinarySearchDisabled);
280
208
                        }
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)0>::SetSortedBinarySearchMode(LookupSearchMode)
ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)0>::SetSortedBinarySearchMode(LookupSearchMode)
Line
Count
Source
274
208
                        {
275
208
                            nSortedBinarySearch =
276
208
                                nSearchMode == LookupSearchMode::BinaryAscending
277
208
                                ? nSearchbAscd
278
208
                                : (nSearchMode == LookupSearchMode::BinaryDescending
279
208
                                   ? nSearchbDesc : nBinarySearchDisabled);
280
208
                        }
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)1>::SetSortedBinarySearchMode(LookupSearchMode)
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)1>::SetSortedBinarySearchMode(LookupSearchMode)
281
282
    void            SetLookupMode( sal_uInt16 nVal )
283
208
                        { nSearchOpCode = nVal; }
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)0>::SetLookupMode(unsigned short)
ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)0>::SetLookupMode(unsigned short)
Line
Count
Source
283
208
                        { nSearchOpCode = nVal; }
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)0, (ScQueryCellIteratorType)1>::SetLookupMode(unsigned short)
Unexecuted instantiation: ScQueryCellIteratorBase<(ScQueryCellIteratorAccess)1, (ScQueryCellIteratorType)1>::SetLookupMode(unsigned short)
284
};
285
286
287
template<>
288
class ScQueryCellIteratorTypeSpecific< ScQueryCellIteratorType::Generic >
289
{
290
protected:
291
    bool HandleItemFound();
292
    bool getThisResult;
293
};
294
295
// The generic query iterator, used e.g. by VLOOKUP.
296
template< ScQueryCellIteratorAccess accessType >
297
class ScQueryCellIterator
298
    : public ScQueryCellIteratorBase< accessType, ScQueryCellIteratorType::Generic >
299
{
300
    typedef ScQueryCellIteratorBase< accessType, ScQueryCellIteratorType::Generic > Base;
301
    // Make base members directly visible here (templated bases need 'this->').
302
    using Base::maParam;
303
    using Base::rDoc;
304
    using Base::mrContext;
305
    using Base::mbReverseSearch;
306
    using Base::nTab;
307
    using Base::nCol;
308
    using Base::nRow;
309
    using Base::InitPos;
310
    using Base::IncPos;
311
    using Base::DecPos;
312
    using Base::bIgnoreMismatchOnLeadingStrings;
313
    using Base::SetStopOnMismatch;
314
    using Base::SetTestEqualCondition;
315
    using Base::BinarySearch;
316
    using typename Base::PositionType;
317
    using Base::maCurPos;
318
    using Base::IsEqualConditionFulfilled;
319
    using Base::bAdvanceQuery;
320
    using Base::StoppedOnMismatch;
321
    using Base::nStopOnMismatch;
322
    using Base::nStopOnMismatchEnabled;
323
    using Base::nTestEqualCondition;
324
    using Base::nTestEqualConditionEnabled;
325
    using Base::nSortedBinarySearch;
326
    using Base::nBinarySearchDisabled;
327
    using Base::PerformQuery;
328
    using Base::getThisResult;
329
    using Base::nBestFitCol;
330
    using Base::nBestFitRow;
331
    using Base::nSearchOpCode;
332
333
    bool GetThis();
334
335
public:
336
    ScQueryCellIterator(ScDocument& rDocument, ScInterpreterContext& rContext, SCTAB nTable,
337
                        const ScQueryParam& aParam, bool bMod, bool bReverse)
338
5.61k
        : Base( rDocument, rContext, nTable, aParam, bMod, bReverse ) {}
Unexecuted instantiation: ScQueryCellIterator<(ScQueryCellIteratorAccess)1>::ScQueryCellIterator(ScDocument&, ScInterpreterContext&, short, ScQueryParam const&, bool, bool)
ScQueryCellIterator<(ScQueryCellIteratorAccess)0>::ScQueryCellIterator(ScDocument&, ScInterpreterContext&, short, ScQueryParam const&, bool, bool)
Line
Count
Source
338
5.61k
        : Base( rDocument, rContext, nTable, aParam, bMod, bReverse ) {}
339
    bool GetFirst();
340
    bool GetNext();
341
8.13k
    SCCOL GetCol() const { return nCol; }
ScQueryCellIterator<(ScQueryCellIteratorAccess)0>::GetCol() const
Line
Count
Source
341
8.13k
    SCCOL GetCol() const { return nCol; }
Unexecuted instantiation: ScQueryCellIterator<(ScQueryCellIteratorAccess)1>::GetCol() const
342
8.13k
    SCROW GetRow() const { return nRow; }
ScQueryCellIterator<(ScQueryCellIteratorAccess)0>::GetRow() const
Line
Count
Source
342
8.13k
    SCROW GetRow() const { return nRow; }
Unexecuted instantiation: ScQueryCellIterator<(ScQueryCellIteratorAccess)1>::GetRow() const
343
344
                    /** In a range assumed to be sorted find either the last of
345
                        a sequence of equal entries or the last being less than
346
                        (or greater than) the queried value. Used by the
347
                        interpreter for [HV]?LOOKUP() and MATCH(). Column and
348
                        row position of the found entry are returned, otherwise
349
                        invalid.
350
351
                        The search does not stop when encountering a string and does not
352
                        assume that no values follow anymore.
353
                        If querying for a string a mismatch on the first
354
                        entry, e.g. column header, is ignored.
355
356
                        @ATTENTION! StopOnMismatch, TestEqualCondition and
357
                        the internal IgnoreMismatchOnLeadingStrings and query
358
                        params are in an undefined state upon return! The
359
                        iterator is not usable anymore except for obtaining the
360
                        number format!
361
                      */
362
    bool            FindEqualOrSortedLastInRange( SCCOL& nFoundCol, SCROW& nFoundRow );
363
};
364
365
typedef ScQueryCellIterator< ScQueryCellIteratorAccess::Direct > ScQueryCellIteratorDirect;
366
367
class ScQueryCellIteratorSortedCache
368
    : public ScQueryCellIterator< ScQueryCellIteratorAccess::SortedCache >
369
{
370
    typedef ScQueryCellIterator< ScQueryCellIteratorAccess::SortedCache > Base;
371
public:
372
    ScQueryCellIteratorSortedCache(ScDocument& rDocument, ScInterpreterContext& rContext,
373
        SCTAB nTable, const ScQueryParam& aParam, bool bMod, bool bReverse )
374
0
    : Base( rDocument, rContext, nTable, aParam, bMod, bReverse ) {}
375
    // Returns true if this iterator can be used for the given query.
376
    static bool CanBeUsed(ScDocument& rDoc, const ScQueryParam& aParam,
377
        SCTAB nTab, const ScFormulaCell* cell, const ScComplexRefData* refData,
378
        ScInterpreterContext& context);
379
};
380
381
382
template<>
383
class ScQueryCellIteratorTypeSpecific< ScQueryCellIteratorType::CountIf >
384
{
385
protected:
386
    bool HandleItemFound();
387
    sal_uInt64 countIfCount;
388
};
389
390
// Used by ScInterpreter::ScCountIf.
391
template< ScQueryCellIteratorAccess accessType >
392
class ScCountIfCellIterator
393
    : public ScQueryCellIteratorBase< accessType, ScQueryCellIteratorType::CountIf >
394
{
395
protected:
396
    typedef ScQueryCellIteratorBase< accessType, ScQueryCellIteratorType::CountIf > Base;
397
    // Make base members directly visible here (templated bases need 'this->').
398
    using Base::maParam;
399
    using Base::rDoc;
400
    using Base::nTab;
401
    using Base::nCol;
402
    using Base::nRow;
403
    using Base::InitPos;
404
    using Base::PerformQuery;
405
    using Base::SetAdvanceQueryParamEntryField;
406
    using Base::countIfCount;
407
408
public:
409
    ScCountIfCellIterator(ScDocument& rDocument, ScInterpreterContext& rContext, SCTAB nTable,
410
                          const ScQueryParam& aParam, bool bMod, bool bReverse)
411
310
        : Base( rDocument, rContext, nTable, aParam, bMod, bReverse ) {}
Unexecuted instantiation: ScCountIfCellIterator<(ScQueryCellIteratorAccess)1>::ScCountIfCellIterator(ScDocument&, ScInterpreterContext&, short, ScQueryParam const&, bool, bool)
ScCountIfCellIterator<(ScQueryCellIteratorAccess)0>::ScCountIfCellIterator(ScDocument&, ScInterpreterContext&, short, ScQueryParam const&, bool, bool)
Line
Count
Source
411
310
        : Base( rDocument, rContext, nTable, aParam, bMod, bReverse ) {}
412
    sal_uInt64 GetCount();
413
};
414
415
typedef ScCountIfCellIterator< ScQueryCellIteratorAccess::Direct > ScCountIfCellIteratorDirect;
416
417
class ScCountIfCellIteratorSortedCache
418
    : public ScCountIfCellIterator< ScQueryCellIteratorAccess::SortedCache >
419
{
420
    typedef ScCountIfCellIterator< ScQueryCellIteratorAccess::SortedCache > Base;
421
public:
422
    ScCountIfCellIteratorSortedCache(ScDocument& rDocument, ScInterpreterContext& rContext,
423
        SCTAB nTable, const ScQueryParam& aParam, bool bMod, bool bReverse)
424
0
    : Base( rDocument, rContext, nTable, aParam, bMod, bReverse ) {}
425
    // Returns true if this iterator can be used for the given query.
426
    static bool CanBeUsed(ScDocument& rDoc, const ScQueryParam& aParam,
427
        SCTAB nTab, const ScFormulaCell* cell, const ScComplexRefData* refData,
428
        ScInterpreterContext& context);
429
};
430
431
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */