xref: /trunk/main/sc/source/core/data/segmenttree.cxx (revision b3f79822)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 #include "segmenttree.hxx"
28 
29 #include <mdds/flat_segment_tree.hpp>
30 
31 #include <limits>
32 
33 using ::std::numeric_limits;
34 
35 // ============================================================================
36 
37 template<typename _ValueType, typename _ExtValueType = _ValueType>
38 class ScFlatSegmentsImpl
39 {
40 public:
41     typedef _ValueType ValueType;
42     typedef _ExtValueType ExtValueType;
43 
44     struct RangeData
45     {
46         SCCOLROW    mnPos1;
47         SCCOLROW    mnPos2;
48         ValueType   mnValue;
49     };
50 
51     ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault);
52     ScFlatSegmentsImpl(const ScFlatSegmentsImpl& r);
53     ~ScFlatSegmentsImpl();
54 
55     void setValue(SCCOLROW nPos1, SCCOLROW nPos2, ValueType nValue);
56     ValueType getValue(SCCOLROW nPos);
57     ExtValueType getSumValue(SCCOLROW nPos1, SCCOLROW nPos2);
58     bool getRangeData(SCCOLROW nPos, RangeData& rData);
59     void removeSegment(SCCOLROW nPos1, SCCOLROW nPos2);
60     void insertSegment(SCCOLROW nPos, SCCOLROW nSize, bool bSkipStartBoundary);
61 
62     SCROW findLastNotOf(ValueType nValue) const;
63 
64     // range iteration
65     bool getFirst(RangeData& rData);
66     bool getNext(RangeData& rData);
67 
enableTreeSearch(bool b)68     void enableTreeSearch(bool b)
69     {
70         mbTreeSearchEnabled = b;
71     }
72 
setInsertFromBack(bool b)73     void setInsertFromBack(bool b)
74     {
75         mbInsertFromBack = b;
76     }
77 
78 private:
79     typedef ::mdds::flat_segment_tree<SCCOLROW, ValueType> fst_type;
80     fst_type maSegments;
81     typename fst_type::const_iterator maItr;
82 
83     bool mbTreeSearchEnabled:1;
84     bool mbInsertFromBack:1;
85 };
86 
87 template<typename _ValueType, typename _ExtValueType>
ScFlatSegmentsImpl(SCCOLROW nMax,ValueType nDefault)88 ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault) :
89     maSegments(0, nMax+1, nDefault),
90     mbTreeSearchEnabled(true),
91     mbInsertFromBack(false)
92 {
93 }
94 
95 template<typename _ValueType, typename _ExtValueType>
ScFlatSegmentsImpl(const ScFlatSegmentsImpl<_ValueType,_ExtValueType> & r)96 ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ScFlatSegmentsImpl(const ScFlatSegmentsImpl<_ValueType, _ExtValueType>& r) :
97     maSegments(r.maSegments),
98     mbTreeSearchEnabled(r.mbTreeSearchEnabled),
99     mbInsertFromBack(r.mbInsertFromBack)
100 {
101 }
102 
103 template<typename _ValueType, typename _ExtValueType>
~ScFlatSegmentsImpl()104 ScFlatSegmentsImpl<_ValueType, _ExtValueType>::~ScFlatSegmentsImpl()
105 {
106 }
107 
108 template<typename _ValueType, typename _ExtValueType>
setValue(SCCOLROW nPos1,SCCOLROW nPos2,ValueType nValue)109 void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::setValue(SCCOLROW nPos1, SCCOLROW nPos2, ValueType nValue)
110 {
111     if (mbInsertFromBack)
112         maSegments.insert_back(nPos1, nPos2+1, nValue);
113     else
114         maSegments.insert_front(nPos1, nPos2+1, nValue);
115 }
116 
117 template<typename _ValueType, typename _ExtValueType>
getValue(SCCOLROW nPos)118 typename ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ValueType ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getValue(SCCOLROW nPos)
119 {
120     ValueType nValue = 0;
121     if (!mbTreeSearchEnabled)
122     {
123         maSegments.search(nPos, nValue);
124         return nValue;
125     }
126 
127     if (!maSegments.is_tree_valid())
128         maSegments.build_tree();
129 
130     maSegments.search_tree(nPos, nValue);
131     return nValue;
132 }
133 
134 template<typename _ValueType, typename _ExtValueType>
135 typename ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ExtValueType
getSumValue(SCCOLROW nPos1,SCCOLROW nPos2)136 ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getSumValue(SCCOLROW nPos1, SCCOLROW nPos2)
137 {
138     RangeData aData;
139     if (!getRangeData(nPos1, aData))
140         return 0;
141 
142     sal_uInt32 nValue = 0;
143 
144     SCROW nCurPos = nPos1;
145     SCROW nEndPos = aData.mnPos2;
146     while (nEndPos <= nPos2)
147     {
148         nValue += aData.mnValue * (nEndPos - nCurPos + 1);
149         nCurPos = nEndPos + 1;
150         if (!getRangeData(nCurPos, aData))
151             break;
152 
153         nEndPos = aData.mnPos2;
154     }
155     if (nCurPos <= nPos2)
156     {
157         nEndPos = ::std::min(nEndPos, nPos2);
158         nValue += aData.mnValue * (nEndPos - nCurPos + 1);
159     }
160     return nValue;
161 }
162 
163 template<typename _ValueType, typename _ExtValueType>
getRangeData(SCCOLROW nPos,RangeData & rData)164 bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getRangeData(SCCOLROW nPos, RangeData& rData)
165 {
166     ValueType nValue;
167     SCCOLROW nPos1, nPos2;
168 
169     if (mbTreeSearchEnabled)
170     {
171         if (!maSegments.is_tree_valid())
172             maSegments.build_tree();
173 
174         if (!maSegments.search_tree(nPos, nValue, &nPos1, &nPos2))
175             return false;
176     }
177     else
178     {
179         // Conduct leaf-node only search.  Faster when searching between range insertion.
180         if (!maSegments.search(nPos, nValue, &nPos1, &nPos2))
181             return false;
182     }
183 
184     rData.mnPos1 = nPos1;
185     rData.mnPos2 = nPos2-1; // end point is not inclusive.
186     rData.mnValue = nValue;
187     return true;
188 }
189 
190 template<typename _ValueType, typename _ExtValueType>
removeSegment(SCCOLROW nPos1,SCCOLROW nPos2)191 void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::removeSegment(SCCOLROW nPos1, SCCOLROW nPos2)
192 {
193     maSegments.shift_left(nPos1, nPos2);
194 }
195 
196 template<typename _ValueType, typename _ExtValueType>
insertSegment(SCCOLROW nPos,SCCOLROW nSize,bool bSkipStartBoundary)197 void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::insertSegment(SCCOLROW nPos, SCCOLROW nSize, bool bSkipStartBoundary)
198 {
199     maSegments.shift_right(nPos, nSize, bSkipStartBoundary);
200 }
201 
202 template<typename _ValueType, typename _ExtValueType>
findLastNotOf(ValueType nValue) const203 SCCOLROW ScFlatSegmentsImpl<_ValueType, _ExtValueType>::findLastNotOf(ValueType nValue) const
204 {
205     SCCOLROW nPos = numeric_limits<SCCOLROW>::max(); // position not found.
206     typename fst_type::const_reverse_iterator itr = maSegments.rbegin(), itrEnd = maSegments.rend();
207     // Note that when searching in reverse direction, we need to skip the first
208     // node, since the right-most leaf node does not store a valid value.
209     for (++itr; itr != itrEnd; ++itr)
210     {
211         if (itr->second != nValue)
212         {
213             nPos = (--itr)->first - 1;
214             break;
215         }
216     }
217     return nPos;
218 }
219 
220 template<typename _ValueType, typename _ExtValueType>
getFirst(RangeData & rData)221 bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getFirst(RangeData& rData)
222 {
223     maItr = maSegments.begin();
224     return getNext(rData);
225 }
226 
227 template<typename _ValueType, typename _ExtValueType>
getNext(RangeData & rData)228 bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getNext(RangeData& rData)
229 {
230     typename fst_type::const_iterator itrEnd = maSegments.end();
231     if (maItr == itrEnd)
232         return false;
233 
234     rData.mnPos1 = maItr->first;
235     rData.mnValue = maItr->second;
236 
237     ++maItr;
238     if (maItr == itrEnd)
239         return false;
240 
241     rData.mnPos2 = maItr->first - 1;
242     return true;
243 }
244 
245 // ============================================================================
246 
247 class ScFlatUInt16SegmentsImpl : public ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>
248 {
249 public:
ScFlatUInt16SegmentsImpl(SCCOLROW nMax,sal_uInt16 nDefault)250     explicit ScFlatUInt16SegmentsImpl(SCCOLROW nMax, sal_uInt16 nDefault) :
251         ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>(nMax, nDefault)
252     {
253     }
254 };
255 
256 // ----------------------------------------------------------------------------
257 
258 class ScFlatBoolSegmentsImpl : public ScFlatSegmentsImpl<bool>
259 {
260 public:
ScFlatBoolSegmentsImpl(SCCOLROW nMax)261     explicit ScFlatBoolSegmentsImpl(SCCOLROW nMax) :
262         ScFlatSegmentsImpl<bool>(nMax, false)
263     {
264     }
265 
266     void setTrue(SCCOLROW nPos1, SCCOLROW nPos2);
267     void setFalse(SCCOLROW nPos1, SCCOLROW nPos2);
268 };
269 
setTrue(SCCOLROW nPos1,SCCOLROW nPos2)270 void ScFlatBoolSegmentsImpl::setTrue(SCCOLROW nPos1, SCCOLROW nPos2)
271 {
272     setValue(nPos1, nPos2, true);
273 }
274 
setFalse(SCCOLROW nPos1,SCCOLROW nPos2)275 void ScFlatBoolSegmentsImpl::setFalse(SCCOLROW nPos1, SCCOLROW nPos2)
276 {
277     setValue(nPos1, nPos2, false);
278 }
279 
280 // ============================================================================
281 
ForwardIterator(ScFlatBoolRowSegments & rSegs)282 ScFlatBoolRowSegments::ForwardIterator::ForwardIterator(ScFlatBoolRowSegments& rSegs) :
283     mrSegs(rSegs), mnCurPos(0), mnLastPos(-1), mbCurValue(false)
284 {
285 }
286 
getValue(SCROW nPos,bool & rVal)287 bool ScFlatBoolRowSegments::ForwardIterator::getValue(SCROW nPos, bool& rVal)
288 {
289     if (nPos >= mnCurPos)
290         // It can only go in a forward direction.
291         mnCurPos = nPos;
292 
293     if (mnCurPos > mnLastPos)
294     {
295         // position not in the current segment.  Update the current value.
296         ScFlatBoolRowSegments::RangeData aData;
297         if (!mrSegs.getRangeData(mnCurPos, aData))
298             return false;
299 
300         mbCurValue = aData.mbValue;
301         mnLastPos = aData.mnRow2;
302     }
303 
304     rVal = mbCurValue;
305     return true;
306 }
307 
getLastPos() const308 SCROW ScFlatBoolRowSegments::ForwardIterator::getLastPos() const
309 {
310     return mnLastPos;
311 }
312 
313 // ----------------------------------------------------------------------------
314 
RangeIterator(ScFlatBoolRowSegments & rSegs)315 ScFlatBoolRowSegments::RangeIterator::RangeIterator(ScFlatBoolRowSegments& rSegs) :
316     mrSegs(rSegs)
317 {
318 }
319 
getFirst(RangeData & rRange)320 bool ScFlatBoolRowSegments::RangeIterator::getFirst(RangeData& rRange)
321 {
322     ScFlatBoolSegmentsImpl::RangeData aData;
323     if (!mrSegs.mpImpl->getFirst(aData))
324         return false;
325 
326     rRange.mnRow1  = static_cast<SCROW>(aData.mnPos1);
327     rRange.mnRow2  = static_cast<SCROW>(aData.mnPos2);
328     rRange.mbValue = static_cast<bool>(aData.mnValue);
329     return true;
330 }
331 
getNext(RangeData & rRange)332 bool ScFlatBoolRowSegments::RangeIterator::getNext(RangeData& rRange)
333 {
334     ScFlatBoolSegmentsImpl::RangeData aData;
335     if (!mrSegs.mpImpl->getNext(aData))
336         return false;
337 
338     rRange.mnRow1  = static_cast<SCROW>(aData.mnPos1);
339     rRange.mnRow2  = static_cast<SCROW>(aData.mnPos2);
340     rRange.mbValue = static_cast<bool>(aData.mnValue);
341     return true;
342 }
343 
344 // ----------------------------------------------------------------------------
345 
ScFlatBoolRowSegments()346 ScFlatBoolRowSegments::ScFlatBoolRowSegments() :
347     mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXROW)))
348 {
349 }
350 
ScFlatBoolRowSegments(const ScFlatBoolRowSegments & r)351 ScFlatBoolRowSegments::ScFlatBoolRowSegments(const ScFlatBoolRowSegments& r) :
352     mpImpl(new ScFlatBoolSegmentsImpl(*r.mpImpl))
353 {
354 }
355 
~ScFlatBoolRowSegments()356 ScFlatBoolRowSegments::~ScFlatBoolRowSegments()
357 {
358 }
359 
setTrue(SCROW nRow1,SCROW nRow2)360 void ScFlatBoolRowSegments::setTrue(SCROW nRow1, SCROW nRow2)
361 {
362     mpImpl->setTrue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
363 }
364 
setFalse(SCROW nRow1,SCROW nRow2)365 void ScFlatBoolRowSegments::setFalse(SCROW nRow1, SCROW nRow2)
366 {
367     mpImpl->setFalse(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
368 }
369 
getValue(SCROW nRow)370 bool ScFlatBoolRowSegments::getValue(SCROW nRow)
371 {
372     return mpImpl->getValue(static_cast<SCCOLROW>(nRow));
373 }
374 
getRangeData(SCROW nRow,RangeData & rData)375 bool ScFlatBoolRowSegments::getRangeData(SCROW nRow, RangeData& rData)
376 {
377     ScFlatBoolSegmentsImpl::RangeData aData;
378     if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nRow), aData))
379         return false;
380 
381     rData.mbValue = aData.mnValue;
382     rData.mnRow1  = static_cast<SCROW>(aData.mnPos1);
383     rData.mnRow2  = static_cast<SCROW>(aData.mnPos2);
384     return true;
385 }
386 
removeSegment(SCROW nRow1,SCROW nRow2)387 void ScFlatBoolRowSegments::removeSegment(SCROW nRow1, SCROW nRow2)
388 {
389     mpImpl->removeSegment(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
390 }
391 
insertSegment(SCROW nRow,SCROW nSize,bool bSkipStartBoundary)392 void ScFlatBoolRowSegments::insertSegment(SCROW nRow, SCROW nSize, bool bSkipStartBoundary)
393 {
394     mpImpl->insertSegment(static_cast<SCCOLROW>(nRow), static_cast<SCCOLROW>(nSize), bSkipStartBoundary);
395 }
396 
findLastNotOf(bool bValue) const397 SCROW ScFlatBoolRowSegments::findLastNotOf(bool bValue) const
398 {
399     return static_cast<SCROW>(mpImpl->findLastNotOf(bValue));
400 }
401 
enableTreeSearch(bool bEnable)402 void ScFlatBoolRowSegments::enableTreeSearch(bool bEnable)
403 {
404     mpImpl->enableTreeSearch(bEnable);
405 }
406 
setInsertFromBack(bool bInsertFromBack)407 void ScFlatBoolRowSegments::setInsertFromBack(bool bInsertFromBack)
408 {
409     mpImpl->setInsertFromBack(bInsertFromBack);
410 }
411 
412 // ============================================================================
413 
ScFlatBoolColSegments()414 ScFlatBoolColSegments::ScFlatBoolColSegments() :
415     mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXCOL)))
416 {
417 }
418 
ScFlatBoolColSegments(const ScFlatBoolColSegments & r)419 ScFlatBoolColSegments::ScFlatBoolColSegments(const ScFlatBoolColSegments& r) :
420     mpImpl(new ScFlatBoolSegmentsImpl(*r.mpImpl))
421 {
422 }
423 
~ScFlatBoolColSegments()424 ScFlatBoolColSegments::~ScFlatBoolColSegments()
425 {
426 }
427 
setTrue(SCCOL nCol1,SCCOL nCol2)428 void ScFlatBoolColSegments::setTrue(SCCOL nCol1, SCCOL nCol2)
429 {
430     mpImpl->setTrue(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2));
431 }
432 
setFalse(SCCOL nCol1,SCCOL nCol2)433 void ScFlatBoolColSegments::setFalse(SCCOL nCol1, SCCOL nCol2)
434 {
435     mpImpl->setFalse(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2));
436 }
437 
getValue(SCCOL nCol)438 bool ScFlatBoolColSegments::getValue(SCCOL nCol)
439 {
440     return mpImpl->getValue(static_cast<SCCOLROW>(nCol));
441 }
442 
getRangeData(SCCOL nCol,RangeData & rData)443 bool ScFlatBoolColSegments::getRangeData(SCCOL nCol, RangeData& rData)
444 {
445     ScFlatBoolSegmentsImpl::RangeData aData;
446     if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nCol), aData))
447         return false;
448 
449     rData.mbValue = aData.mnValue;
450     rData.mnCol1  = static_cast<SCCOL>(aData.mnPos1);
451     rData.mnCol2  = static_cast<SCCOL>(aData.mnPos2);
452     return true;
453 }
454 
removeSegment(SCCOL nCol1,SCCOL nCol2)455 void ScFlatBoolColSegments::removeSegment(SCCOL nCol1, SCCOL nCol2)
456 {
457     mpImpl->removeSegment(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2));
458 }
459 
insertSegment(SCCOL nCol,SCCOL nSize,bool bSkipStartBoundary)460 void ScFlatBoolColSegments::insertSegment(SCCOL nCol, SCCOL nSize, bool bSkipStartBoundary)
461 {
462     mpImpl->insertSegment(static_cast<SCCOLROW>(nCol), static_cast<SCCOLROW>(nSize), bSkipStartBoundary);
463 }
464 
enableTreeSearch(bool bEnable)465 void ScFlatBoolColSegments::enableTreeSearch(bool bEnable)
466 {
467     mpImpl->enableTreeSearch(bEnable);
468 }
469 
setInsertFromBack(bool bInsertFromBack)470 void ScFlatBoolColSegments::setInsertFromBack(bool bInsertFromBack)
471 {
472     mpImpl->setInsertFromBack(bInsertFromBack);
473 }
474 
475 // ============================================================================
476 
477 
478 // ============================================================================
479 
ForwardIterator(ScFlatUInt16RowSegments & rSegs)480 ScFlatUInt16RowSegments::ForwardIterator::ForwardIterator(ScFlatUInt16RowSegments& rSegs) :
481     mrSegs(rSegs), mnCurPos(0), mnLastPos(-1), mnCurValue(0)
482 {
483 }
484 
getValue(SCROW nPos,sal_uInt16 & rVal)485 bool ScFlatUInt16RowSegments::ForwardIterator::getValue(SCROW nPos, sal_uInt16& rVal)
486 {
487     if (nPos >= mnCurPos)
488         // It can only go in a forward direction.
489         mnCurPos = nPos;
490 
491     if (mnCurPos > mnLastPos)
492     {
493         // position not in the current segment.  Update the current value.
494         ScFlatUInt16RowSegments::RangeData aData;
495         if (!mrSegs.getRangeData(mnCurPos, aData))
496             return false;
497 
498         mnCurValue = aData.mnValue;
499         mnLastPos = aData.mnRow2;
500     }
501 
502     rVal = mnCurValue;
503     return true;
504 }
505 
getLastPos() const506 SCROW ScFlatUInt16RowSegments::ForwardIterator::getLastPos() const
507 {
508     return mnLastPos;
509 }
510 
511 // ----------------------------------------------------------------------------
512 
ScFlatUInt16RowSegments(sal_uInt16 nDefault)513 ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(sal_uInt16 nDefault) :
514     mpImpl(new ScFlatUInt16SegmentsImpl(static_cast<SCCOLROW>(MAXROW), nDefault))
515 {
516 }
517 
ScFlatUInt16RowSegments(const ScFlatUInt16RowSegments & r)518 ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(const ScFlatUInt16RowSegments& r) :
519     mpImpl(new ScFlatUInt16SegmentsImpl(*r.mpImpl))
520 {
521 }
522 
~ScFlatUInt16RowSegments()523 ScFlatUInt16RowSegments::~ScFlatUInt16RowSegments()
524 {
525 }
526 
setValue(SCROW nRow1,SCROW nRow2,sal_uInt16 nValue)527 void ScFlatUInt16RowSegments::setValue(SCROW nRow1, SCROW nRow2, sal_uInt16 nValue)
528 {
529     mpImpl->setValue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2), nValue);
530 }
531 
getValue(SCROW nRow)532 sal_uInt16 ScFlatUInt16RowSegments::getValue(SCROW nRow)
533 {
534     return mpImpl->getValue(static_cast<SCCOLROW>(nRow));
535 }
536 
getSumValue(SCROW nRow1,SCROW nRow2)537 sal_uInt32 ScFlatUInt16RowSegments::getSumValue(SCROW nRow1, SCROW nRow2)
538 {
539     return mpImpl->getSumValue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
540 }
541 
getRangeData(SCROW nRow,RangeData & rData)542 bool ScFlatUInt16RowSegments::getRangeData(SCROW nRow, RangeData& rData)
543 {
544     ScFlatUInt16SegmentsImpl::RangeData aData;
545     if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nRow), aData))
546         return false;
547 
548     rData.mnRow1  = aData.mnPos1;
549     rData.mnRow2  = aData.mnPos2;
550     rData.mnValue = aData.mnValue;
551     return true;
552 }
553 
removeSegment(SCROW nRow1,SCROW nRow2)554 void ScFlatUInt16RowSegments::removeSegment(SCROW nRow1, SCROW nRow2)
555 {
556     mpImpl->removeSegment(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
557 }
558 
insertSegment(SCROW nRow,SCROW nSize,bool bSkipStartBoundary)559 void ScFlatUInt16RowSegments::insertSegment(SCROW nRow, SCROW nSize, bool bSkipStartBoundary)
560 {
561     mpImpl->insertSegment(static_cast<SCCOLROW>(nRow), static_cast<SCCOLROW>(nSize), bSkipStartBoundary);
562 }
563 
findLastNotOf(sal_uInt16 nValue) const564 SCROW ScFlatUInt16RowSegments::findLastNotOf(sal_uInt16 nValue) const
565 {
566     return static_cast<SCROW>(mpImpl->findLastNotOf(nValue));
567 }
568 
enableTreeSearch(bool bEnable)569 void ScFlatUInt16RowSegments::enableTreeSearch(bool bEnable)
570 {
571     mpImpl->enableTreeSearch(bEnable);
572 }
573 
setInsertFromBack(bool bInsertFromBack)574 void ScFlatUInt16RowSegments::setInsertFromBack(bool bInsertFromBack)
575 {
576     mpImpl->setInsertFromBack(bInsertFromBack);
577 }
578 
579