1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <segmenttree.hxx>
21 #include <o3tl/safeint.hxx>
22 #include <mdds/flat_segment_tree.hpp>
23 #include <sal/log.hxx>
26 #include <string_view>
29 using ::std::numeric_limits
;
33 template<typename ValueType_
, typename ExtValueType_
= ValueType_
>
34 class ScFlatSegmentsImpl
37 typedef ValueType_ ValueType
;
38 typedef ExtValueType_ ExtValueType
;
47 ScFlatSegmentsImpl(SCCOLROW nMax
, ValueType nDefault
);
48 ScFlatSegmentsImpl(const ScFlatSegmentsImpl
& r
);
50 bool setValue(SCCOLROW nPos1
, SCCOLROW nPos2
, ValueType nValue
);
51 void setValueIf(SCCOLROW nPos1
, SCCOLROW nPos2
, ValueType nValue
, const std::function
<bool(ValueType
)>& rPredicate
);
52 ValueType
getValue(SCCOLROW nPos
);
53 sal_uInt64
getSumValue(SCCOLROW nPos1
, SCCOLROW nPos2
);
54 bool getRangeData(SCCOLROW nPos
, RangeData
& rData
);
55 bool getRangeDataLeaf(SCCOLROW nPos
, RangeData
& rData
);
56 void removeSegment(SCCOLROW nPos1
, SCCOLROW nPos2
);
57 void insertSegment(SCCOLROW nPos
, SCCOLROW nSize
, bool bSkipStartBoundary
);
59 SCCOLROW
findLastTrue(ValueType nValue
) const;
62 bool getFirst(RangeData
& rData
);
63 bool getNext(RangeData
& rData
);
65 void enableTreeSearch(bool b
)
67 mbTreeSearchEnabled
= b
;
73 typedef ::mdds::flat_segment_tree
<SCCOLROW
, ValueType
> fst_type
;
75 typename
fst_type::const_iterator maItr
;
77 bool mbTreeSearchEnabled
:1;
82 template<typename ValueType_
, typename ExtValueType_
>
83 ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::ScFlatSegmentsImpl(SCCOLROW nMax
, ValueType nDefault
) :
84 maSegments(0, nMax
+1, nDefault
),
85 mbTreeSearchEnabled(true)
89 template<typename ValueType_
, typename ExtValueType_
>
90 ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::ScFlatSegmentsImpl(const ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>& r
) :
91 maSegments(r
.maSegments
),
92 mbTreeSearchEnabled(r
.mbTreeSearchEnabled
)
96 template<typename ValueType_
, typename ExtValueType_
>
97 bool ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::setValue(SCCOLROW nPos1
, SCCOLROW nPos2
, ValueType nValue
)
99 ::std::pair
<typename
fst_type::const_iterator
, bool> ret
;
100 ret
= maSegments
.insert(maItr
, nPos1
, nPos2
+1, nValue
);
105 template<typename ValueType_
, typename ExtValueType_
>
106 void ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::setValueIf(SCCOLROW nPos1
, SCCOLROW nPos2
,
107 ValueType nValue
, const std::function
<bool(ValueType
)>& rPredicate
)
109 SCCOLROW nCurrentStartRow
= nPos1
;
110 while (nCurrentStartRow
<= nPos2
)
112 RangeData aRangeData
;
113 getRangeData(nCurrentStartRow
, aRangeData
);
114 if (rPredicate(aRangeData
.mnValue
))
116 // set value from current iteration point on, til end of range.
117 // Note that aRangeData may well contain much lower values for nPos1
118 setValue(nCurrentStartRow
, std::min
<SCCOLROW
>(nPos2
, aRangeData
.mnPos2
), nValue
);
121 // even if nPos2 is bigger than nPos2 this should terminate the loop
122 nCurrentStartRow
= aRangeData
.mnPos2
+ 1;
126 template<typename ValueType_
, typename ExtValueType_
>
127 typename ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::ValueType ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::getValue(SCCOLROW nPos
)
129 ValueType nValue
= 0;
130 if (!mbTreeSearchEnabled
)
132 maSegments
.search(nPos
, nValue
);
136 if (!maSegments
.is_tree_valid())
138 assert(!ScGlobal::bThreadedGroupCalcInProgress
);
139 maSegments
.build_tree();
142 maSegments
.search_tree(nPos
, nValue
);
146 template<typename ValueType_
, typename ExtValueType_
>
147 sal_uInt64 ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::getSumValue(SCCOLROW nPos1
, SCCOLROW nPos2
)
149 if (mbTreeSearchEnabled
)
152 if (!maSegments
.is_tree_valid())
154 assert(!ScGlobal::bThreadedGroupCalcInProgress
);
155 maSegments
.build_tree();
159 auto [it
, found
] = maSegments
.search_tree(nPos1
, aData
.mnValue
, &aData
.mnPos1
, &aData
.mnPos2
);
162 aData
.mnPos2
= aData
.mnPos2
-1; // end point is not inclusive.
164 sal_uInt64 nValue
= 0;
166 SCROW nCurPos
= nPos1
;
167 SCROW nEndPos
= aData
.mnPos2
;
168 while (nEndPos
<= nPos2
)
171 if (o3tl::checked_multiply
<sal_uInt64
>(aData
.mnValue
, nEndPos
- nCurPos
+ 1, nRes
))
173 SAL_WARN("sc.core", "row height overflow");
174 nRes
= SAL_MAX_INT64
;
176 nValue
= o3tl::saturating_add(nValue
, nRes
);
177 nCurPos
= nEndPos
+ 1;
178 auto itPair
= maSegments
.search(it
, nCurPos
, aData
.mnValue
, &aData
.mnPos1
, &aData
.mnPos2
);
182 aData
.mnPos2
= aData
.mnPos2
-1; // end point is not inclusive.
183 nEndPos
= aData
.mnPos2
;
185 if (nCurPos
<= nPos2
)
187 nEndPos
= ::std::min(nEndPos
, nPos2
);
189 if (o3tl::checked_multiply
<sal_uInt64
>(aData
.mnValue
, nEndPos
- nCurPos
+ 1, nRes
))
191 SAL_WARN("sc.core", "row height overflow");
192 nRes
= SAL_MAX_INT64
;
194 nValue
= o3tl::saturating_add(nValue
, nRes
);
201 if (!getRangeDataLeaf(nPos1
, aData
))
204 sal_uInt64 nValue
= 0;
206 SCROW nCurPos
= nPos1
;
207 SCROW nEndPos
= aData
.mnPos2
;
208 while (nEndPos
<= nPos2
)
211 if (o3tl::checked_multiply
<sal_uInt64
>(aData
.mnValue
, nEndPos
- nCurPos
+ 1, nRes
))
213 SAL_WARN("sc.core", "row height overflow");
214 nRes
= SAL_MAX_INT64
;
216 nValue
= o3tl::saturating_add(nValue
, nRes
);
217 nCurPos
= nEndPos
+ 1;
218 if (!getRangeDataLeaf(nCurPos
, aData
))
221 nEndPos
= aData
.mnPos2
;
223 if (nCurPos
<= nPos2
)
225 nEndPos
= ::std::min(nEndPos
, nPos2
);
227 if (o3tl::checked_multiply
<sal_uInt64
>(aData
.mnValue
, nEndPos
- nCurPos
+ 1, nRes
))
229 SAL_WARN("sc.core", "row height overflow");
230 nRes
= SAL_MAX_INT64
;
232 nValue
= o3tl::saturating_add(nValue
, nRes
);
238 template<typename ValueType_
, typename ExtValueType_
>
239 bool ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::getRangeData(SCCOLROW nPos
, RangeData
& rData
)
241 if (!mbTreeSearchEnabled
)
242 return getRangeDataLeaf(nPos
, rData
);
244 if (!maSegments
.is_tree_valid())
246 assert(!ScGlobal::bThreadedGroupCalcInProgress
);
247 maSegments
.build_tree();
250 auto [it
,found
] = maSegments
.search_tree(nPos
, rData
.mnValue
, &rData
.mnPos1
, &rData
.mnPos2
);
253 maItr
= it
; // cache the iterator to speed up ForwardIterator.
254 rData
.mnPos2
= rData
.mnPos2
-1; // end point is not inclusive.
258 template<typename ValueType_
, typename ExtValueType_
>
259 bool ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::getRangeDataLeaf(SCCOLROW nPos
, RangeData
& rData
)
261 // Conduct leaf-node only search. Faster when searching between range insertion.
262 const ::std::pair
<typename
fst_type::const_iterator
, bool> &ret
=
263 maSegments
.search(maItr
, nPos
, rData
.mnValue
, &rData
.mnPos1
, &rData
.mnPos2
);
270 rData
.mnPos2
= rData
.mnPos2
-1; // end point is not inclusive.
274 template<typename ValueType_
, typename ExtValueType_
>
275 void ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::removeSegment(SCCOLROW nPos1
, SCCOLROW nPos2
)
277 maSegments
.shift_left(nPos1
, nPos2
);
278 maItr
= maSegments
.begin();
281 template<typename ValueType_
, typename ExtValueType_
>
282 void ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::insertSegment(SCCOLROW nPos
, SCCOLROW nSize
, bool bSkipStartBoundary
)
284 maSegments
.shift_right(nPos
, nSize
, bSkipStartBoundary
);
285 maItr
= maSegments
.begin();
288 template<typename ValueType_
, typename ExtValueType_
>
289 SCCOLROW ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::findLastTrue(ValueType nValue
) const
291 SCCOLROW nPos
= numeric_limits
<SCCOLROW
>::max(); // position not found.
292 typename
fst_type::const_reverse_iterator itr
= maSegments
.rbegin(), itrEnd
= maSegments
.rend();
293 // Note that when searching in reverse direction, we need to skip the first
294 // node, since the right-most leaf node does not store a valid value.
295 for (++itr
; itr
!= itrEnd
; ++itr
)
297 if (itr
->second
!= nValue
)
299 nPos
= (--itr
)->first
- 1;
306 template<typename ValueType_
, typename ExtValueType_
>
307 bool ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::getFirst(RangeData
& rData
)
309 maItr
= maSegments
.begin();
310 return getNext(rData
);
313 template<typename ValueType_
, typename ExtValueType_
>
314 bool ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::getNext(RangeData
& rData
)
316 typename
fst_type::const_iterator itrEnd
= maSegments
.end();
320 rData
.mnPos1
= maItr
->first
;
321 rData
.mnValue
= maItr
->second
;
327 rData
.mnPos2
= maItr
->first
- 1;
331 template<typename ValueType_
, typename ExtValueType_
>
332 void ScFlatSegmentsImpl
<ValueType_
, ExtValueType_
>::makeReady()
334 assert(!ScGlobal::bThreadedGroupCalcInProgress
);
335 if (!maSegments
.is_tree_valid())
336 maSegments
.build_tree();
339 class ScFlatUInt16SegmentsImpl
: public ScFlatSegmentsImpl
<sal_uInt16
, sal_uInt32
>
342 explicit ScFlatUInt16SegmentsImpl(SCCOLROW nMax
, sal_uInt16 nDefault
) :
343 ScFlatSegmentsImpl
<sal_uInt16
, sal_uInt32
>(nMax
, nDefault
)
348 class ScFlatBoolSegmentsImpl
: public ScFlatSegmentsImpl
<bool>
351 explicit ScFlatBoolSegmentsImpl(SCCOLROW nMax
) :
352 ScFlatSegmentsImpl
<bool>(nMax
, false)
356 bool setTrue(SCCOLROW nPos1
, SCCOLROW nPos2
);
357 bool setFalse(SCCOLROW nPos1
, SCCOLROW nPos2
);
360 bool ScFlatBoolSegmentsImpl::setTrue(SCCOLROW nPos1
, SCCOLROW nPos2
)
362 return setValue(nPos1
, nPos2
, true);
365 bool ScFlatBoolSegmentsImpl::setFalse(SCCOLROW nPos1
, SCCOLROW nPos2
)
367 return setValue(nPos1
, nPos2
, false);
370 ScFlatBoolRowSegments::ForwardIterator::ForwardIterator(ScFlatBoolRowSegments
& rSegs
) :
371 mrSegs(rSegs
), mnCurPos(0), mnLastPos(-1), mbCurValue(false)
375 bool ScFlatBoolRowSegments::ForwardIterator::getValue(SCROW nPos
, bool& rVal
)
377 if (nPos
>= mnCurPos
)
378 // It can only go in a forward direction.
381 if (mnCurPos
> mnLastPos
)
383 // position not in the current segment. Update the current value.
384 ScFlatBoolRowSegments::RangeData aData
;
385 if (!mrSegs
.getRangeData(mnCurPos
, aData
))
388 mbCurValue
= aData
.mbValue
;
389 mnLastPos
= aData
.mnRow2
;
396 ScFlatBoolRowSegments::RangeIterator::RangeIterator(ScFlatBoolRowSegments
const & rSegs
) :
401 bool ScFlatBoolRowSegments::RangeIterator::getFirst(RangeData
& rRange
)
403 ScFlatBoolSegmentsImpl::RangeData aData
;
404 if (!mrSegs
.mpImpl
->getFirst(aData
))
407 rRange
.mnRow1
= static_cast<SCROW
>(aData
.mnPos1
);
408 rRange
.mnRow2
= static_cast<SCROW
>(aData
.mnPos2
);
409 rRange
.mbValue
= static_cast<bool>(aData
.mnValue
);
413 bool ScFlatBoolRowSegments::RangeIterator::getNext(RangeData
& rRange
)
415 ScFlatBoolSegmentsImpl::RangeData aData
;
416 if (!mrSegs
.mpImpl
->getNext(aData
))
419 rRange
.mnRow1
= static_cast<SCROW
>(aData
.mnPos1
);
420 rRange
.mnRow2
= static_cast<SCROW
>(aData
.mnPos2
);
421 rRange
.mbValue
= static_cast<bool>(aData
.mnValue
);
425 ScFlatBoolRowSegments::ScFlatBoolRowSegments(SCROW nMaxRow
) :
426 mpImpl(new ScFlatBoolSegmentsImpl(nMaxRow
))
430 ScFlatBoolRowSegments::ScFlatBoolRowSegments(const ScFlatBoolRowSegments
& r
) :
431 mpImpl(new ScFlatBoolSegmentsImpl(*r
.mpImpl
))
435 ScFlatBoolRowSegments::~ScFlatBoolRowSegments()
439 bool ScFlatBoolRowSegments::setTrue(SCROW nRow1
, SCROW nRow2
)
441 return mpImpl
->setTrue(static_cast<SCCOLROW
>(nRow1
), static_cast<SCCOLROW
>(nRow2
));
444 bool ScFlatBoolRowSegments::setFalse(SCROW nRow1
, SCROW nRow2
)
446 return mpImpl
->setFalse(static_cast<SCCOLROW
>(nRow1
), static_cast<SCCOLROW
>(nRow2
));
449 bool ScFlatBoolRowSegments::getRangeData(SCROW nRow
, RangeData
& rData
) const
451 ScFlatBoolSegmentsImpl::RangeData aData
;
452 if (!mpImpl
->getRangeData(static_cast<SCCOLROW
>(nRow
), aData
))
455 rData
.mbValue
= aData
.mnValue
;
456 rData
.mnRow1
= static_cast<SCROW
>(aData
.mnPos1
);
457 rData
.mnRow2
= static_cast<SCROW
>(aData
.mnPos2
);
461 bool ScFlatBoolRowSegments::getRangeDataLeaf(SCROW nRow
, RangeData
& rData
)
463 ScFlatBoolSegmentsImpl::RangeData aData
;
464 if (!mpImpl
->getRangeDataLeaf(static_cast<SCCOLROW
>(nRow
), aData
))
467 rData
.mbValue
= aData
.mnValue
;
468 rData
.mnRow1
= static_cast<SCROW
>(aData
.mnPos1
);
469 rData
.mnRow2
= static_cast<SCROW
>(aData
.mnPos2
);
473 void ScFlatBoolRowSegments::removeSegment(SCROW nRow1
, SCROW nRow2
)
475 mpImpl
->removeSegment(static_cast<SCCOLROW
>(nRow1
), static_cast<SCCOLROW
>(nRow2
));
478 void ScFlatBoolRowSegments::insertSegment(SCROW nRow
, SCROW nSize
)
480 mpImpl
->insertSegment(static_cast<SCCOLROW
>(nRow
), static_cast<SCCOLROW
>(nSize
), true/*bSkipStartBoundary*/);
483 SCROW
ScFlatBoolRowSegments::findLastTrue() const
485 return mpImpl
->findLastTrue(false);
488 void ScFlatBoolRowSegments::makeReady()
493 OString
ScFlatBoolRowSegments::dumpAsString()
499 while (getRangeData(nRow
, aRange
))
502 aSegment
= (aRange
.mbValue
? std::string_view("1") : std::string_view("0")) + OString::Concat(":");
506 aSegment
+= OString::number(aRange
.mnRow2
) + " ";
508 nRow
= aRange
.mnRow2
+ 1;
514 ScFlatBoolColSegments::ScFlatBoolColSegments(SCCOL nMaxCol
) :
515 mpImpl(new ScFlatBoolSegmentsImpl(nMaxCol
))
519 ScFlatBoolColSegments::ScFlatBoolColSegments(const ScFlatBoolColSegments
& r
) :
520 mpImpl(new ScFlatBoolSegmentsImpl(*r
.mpImpl
))
524 ScFlatBoolColSegments::~ScFlatBoolColSegments()
528 bool ScFlatBoolColSegments::setTrue(SCCOL nCol1
, SCCOL nCol2
)
530 return mpImpl
->setTrue(static_cast<SCCOLROW
>(nCol1
), static_cast<SCCOLROW
>(nCol2
));
533 bool ScFlatBoolColSegments::setFalse(SCCOL nCol1
, SCCOL nCol2
)
535 return mpImpl
->setFalse(static_cast<SCCOLROW
>(nCol1
), static_cast<SCCOLROW
>(nCol2
));
538 bool ScFlatBoolColSegments::getRangeData(SCCOL nCol
, RangeData
& rData
)
540 ScFlatBoolSegmentsImpl::RangeData aData
;
541 if (!mpImpl
->getRangeData(static_cast<SCCOLROW
>(nCol
), aData
))
544 rData
.mbValue
= aData
.mnValue
;
545 rData
.mnCol1
= static_cast<SCCOL
>(aData
.mnPos1
);
546 rData
.mnCol2
= static_cast<SCCOL
>(aData
.mnPos2
);
550 void ScFlatBoolColSegments::removeSegment(SCCOL nCol1
, SCCOL nCol2
)
552 mpImpl
->removeSegment(static_cast<SCCOLROW
>(nCol1
), static_cast<SCCOLROW
>(nCol2
));
555 void ScFlatBoolColSegments::insertSegment(SCCOL nCol
, SCCOL nSize
)
557 mpImpl
->insertSegment(static_cast<SCCOLROW
>(nCol
), static_cast<SCCOLROW
>(nSize
), true/*bSkipStartBoundary*/);
560 void ScFlatBoolColSegments::makeReady()
565 OString
ScFlatBoolColSegments::dumpAsString()
571 while (getRangeData(nCol
, aRange
))
574 aSegment
= (aRange
.mbValue
? OString::Concat("1") : OString::Concat("0")) + OString::Concat(":");
578 aSegment
+= OString::number(aRange
.mnCol2
) + " ";
580 nCol
= aRange
.mnCol2
+ 1;
586 ScFlatUInt16RowSegments::ForwardIterator::ForwardIterator(ScFlatUInt16RowSegments
& rSegs
) :
587 mrSegs(rSegs
), mnCurPos(0), mnLastPos(-1), mnCurValue(0)
591 bool ScFlatUInt16RowSegments::ForwardIterator::getValue(SCROW nPos
, sal_uInt16
& rVal
)
593 if (nPos
>= mnCurPos
)
594 // It can only go in a forward direction.
597 if (mnCurPos
> mnLastPos
)
599 // position not in the current segment. Update the current value.
600 ScFlatUInt16SegmentsImpl::RangeData aData
;
603 // first time in this method, use the tree search based method
604 if (!mrSegs
.mpImpl
->getRangeData(mnCurPos
, aData
))
609 // but on subsequent calls, use the leaf method, which is faster
610 // because we have a cached iterator.
611 if (!mrSegs
.mpImpl
->getRangeDataLeaf(mnCurPos
, aData
))
615 mnCurValue
= aData
.mnValue
;
616 mnLastPos
= aData
.mnPos2
;
623 ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(SCROW nMaxRow
, sal_uInt16 nDefault
) :
624 mpImpl(new ScFlatUInt16SegmentsImpl(nMaxRow
, nDefault
))
628 ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(const ScFlatUInt16RowSegments
& r
) :
629 mpImpl(new ScFlatUInt16SegmentsImpl(*r
.mpImpl
))
633 ScFlatUInt16RowSegments::~ScFlatUInt16RowSegments()
637 void ScFlatUInt16RowSegments::setValue(SCROW nRow1
, SCROW nRow2
, sal_uInt16 nValue
)
639 mpImpl
->setValue(static_cast<SCCOLROW
>(nRow1
), static_cast<SCCOLROW
>(nRow2
), nValue
);
642 sal_uInt16
ScFlatUInt16RowSegments::getValue(SCROW nRow
)
644 return mpImpl
->getValue(static_cast<SCCOLROW
>(nRow
));
647 sal_uInt64
ScFlatUInt16RowSegments::getSumValue(SCROW nRow1
, SCROW nRow2
)
649 return mpImpl
->getSumValue(static_cast<SCCOLROW
>(nRow1
), static_cast<SCCOLROW
>(nRow2
));
652 bool ScFlatUInt16RowSegments::getRangeData(SCROW nRow
, RangeData
& rData
)
654 ScFlatUInt16SegmentsImpl::RangeData aData
;
655 if (!mpImpl
->getRangeData(static_cast<SCCOLROW
>(nRow
), aData
))
658 rData
.mnRow1
= aData
.mnPos1
;
659 rData
.mnRow2
= aData
.mnPos2
;
660 rData
.mnValue
= aData
.mnValue
;
664 void ScFlatUInt16RowSegments::removeSegment(SCROW nRow1
, SCROW nRow2
)
666 mpImpl
->removeSegment(static_cast<SCCOLROW
>(nRow1
), static_cast<SCCOLROW
>(nRow2
));
669 void ScFlatUInt16RowSegments::insertSegment(SCROW nRow
, SCROW nSize
)
671 mpImpl
->insertSegment(static_cast<SCCOLROW
>(nRow
), static_cast<SCCOLROW
>(nSize
), false/*bSkipStartBoundary*/);
674 SCROW
ScFlatUInt16RowSegments::findLastTrue(sal_uInt16 nValue
) const
676 return mpImpl
->findLastTrue(nValue
);
679 void ScFlatUInt16RowSegments::enableTreeSearch(bool bEnable
)
681 mpImpl
->enableTreeSearch(bEnable
);
684 void ScFlatUInt16RowSegments::setValueIf(SCROW nRow1
, SCROW nRow2
, sal_uInt16 nValue
, const std::function
<bool(sal_uInt16
)>& rPredicate
)
686 mpImpl
->setValueIf(static_cast<SCCOLROW
>(nRow1
), static_cast<SCCOLROW
>(nRow2
), nValue
, rPredicate
);
689 void ScFlatUInt16RowSegments::makeReady()
694 OString
ScFlatUInt16RowSegments::dumpAsString()
700 while (getRangeData(nRow
, aRange
))
702 aSegment
= OString::number(aRange
.mnValue
) + ":" +
703 OString::number(aRange
.mnRow2
) + " ";
705 nRow
= aRange
.mnRow2
+ 1;
711 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */