22#include <mdds/flat_segment_tree.hpp>
29using ::std::numeric_limits;
33template<
typename ValueType_,
typename ExtValueType_ = ValueType_>
34class ScFlatSegmentsImpl
38 typedef ExtValueType_ ExtValueType;
48 ScFlatSegmentsImpl(
const ScFlatSegmentsImpl& r);
54 bool getRangeData(
SCCOLROW nPos, RangeData& rData);
55 bool getRangeDataLeaf(
SCCOLROW nPos, RangeData& rData);
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;
82template<
typename ValueType_,
typename ExtValueType_>
83ScFlatSegmentsImpl<ValueType_, ExtValueType_>::ScFlatSegmentsImpl(
SCCOLROW nMax,
ValueType nDefault) :
84 maSegments(0, nMax+1, nDefault),
85 mbTreeSearchEnabled(true)
89template<
typename ValueType_,
typename ExtValueType_>
90ScFlatSegmentsImpl<ValueType_, ExtValueType_>::ScFlatSegmentsImpl(
const ScFlatSegmentsImpl<ValueType_, ExtValueType_>& r) :
91 maSegments(r.maSegments),
92 mbTreeSearchEnabled(r.mbTreeSearchEnabled)
96template<
typename ValueType_,
typename ExtValueType_>
99 ::std::pair<typename fst_type::const_iterator, bool> ret;
100 ret = maSegments.insert(maItr, nPos1, nPos2+1, nValue);
105template<
typename ValueType_,
typename ExtValueType_>
106void ScFlatSegmentsImpl<ValueType_, ExtValueType_>::setValueIf(
SCCOLROW nPos1,
SCCOLROW nPos2,
110 while (nCurrentStartRow <= nPos2)
112 RangeData aRangeData;
113 getRangeData(nCurrentStartRow, aRangeData);
114 if (rPredicate(aRangeData.mnValue))
118 setValue(nCurrentStartRow, std::min<SCCOLROW>(nPos2, aRangeData.mnPos2), nValue);
122 nCurrentStartRow = aRangeData.mnPos2 + 1;
126template<
typename ValueType_,
typename ExtValueType_>
127typename ScFlatSegmentsImpl<ValueType_, ExtValueType_>::ValueType ScFlatSegmentsImpl<ValueType_, ExtValueType_>::getValue(
SCCOLROW nPos)
130 if (!mbTreeSearchEnabled)
132 maSegments.search(nPos, nValue);
136 if (!maSegments.is_tree_valid())
139 maSegments.build_tree();
142 maSegments.search_tree(nPos, nValue);
146template<
typename ValueType_,
typename ExtValueType_>
147sal_uInt64 ScFlatSegmentsImpl<ValueType_, ExtValueType_>::getSumValue(
SCCOLROW nPos1,
SCCOLROW nPos2)
149 if (mbTreeSearchEnabled)
152 if (!maSegments.is_tree_valid())
155 maSegments.build_tree();
159 auto [it, found] = maSegments.search_tree(nPos1,
aData.mnValue, &
aData.mnPos1, &
aData.mnPos2);
166 SCROW nCurPos = nPos1;
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");
177 nCurPos = nEndPos + 1;
178 auto itPair = maSegments.search(it, nCurPos,
aData.mnValue, &
aData.mnPos1, &
aData.mnPos2);
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");
201 if (!getRangeDataLeaf(nPos1, aData))
206 SCROW nCurPos = nPos1;
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");
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");
238template<
typename ValueType_,
typename ExtValueType_>
239bool ScFlatSegmentsImpl<ValueType_, ExtValueType_>::getRangeData(
SCCOLROW nPos, RangeData& rData)
241 if (!mbTreeSearchEnabled)
242 return getRangeDataLeaf(nPos, rData);
244 if (!maSegments.is_tree_valid())
247 maSegments.build_tree();
250 auto [it,found] = maSegments.search_tree(nPos, rData.mnValue, &rData.mnPos1, &rData.mnPos2);
254 rData.mnPos2 = rData.mnPos2-1;
258template<
typename ValueType_,
typename ExtValueType_>
259bool ScFlatSegmentsImpl<ValueType_, ExtValueType_>::getRangeDataLeaf(
SCCOLROW nPos, RangeData& rData)
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;
274template<
typename ValueType_,
typename ExtValueType_>
275void ScFlatSegmentsImpl<ValueType_, ExtValueType_>::removeSegment(
SCCOLROW nPos1,
SCCOLROW nPos2)
277 maSegments.shift_left(nPos1, nPos2);
278 maItr = maSegments.begin();
281template<
typename ValueType_,
typename ExtValueType_>
282void ScFlatSegmentsImpl<ValueType_, ExtValueType_>::insertSegment(
SCCOLROW nPos,
SCCOLROW nSize,
bool bSkipStartBoundary)
284 maSegments.shift_right(nPos, nSize, bSkipStartBoundary);
285 maItr = maSegments.begin();
288template<
typename ValueType_,
typename ExtValueType_>
289SCCOLROW ScFlatSegmentsImpl<ValueType_, ExtValueType_>::findLastTrue(
ValueType nValue)
const
292 typename fst_type::const_reverse_iterator itr = maSegments.rbegin(), itrEnd = maSegments.rend();
295 for (++itr; itr != itrEnd; ++itr)
297 if (itr->second != nValue)
299 nPos = (--itr)->first - 1;
306template<
typename ValueType_,
typename ExtValueType_>
307bool ScFlatSegmentsImpl<ValueType_, ExtValueType_>::getFirst(RangeData& rData)
309 maItr = maSegments.begin();
310 return getNext(rData);
313template<
typename ValueType_,
typename ExtValueType_>
314bool 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;
331template<
typename ValueType_,
typename ExtValueType_>
332void ScFlatSegmentsImpl<ValueType_, ExtValueType_>::makeReady()
335 if (!maSegments.is_tree_valid())
336 maSegments.build_tree();
343 ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>(nMax, nDefault)
352 ScFlatSegmentsImpl<bool>(nMax, false)
362 return setValue(nPos1, nPos2,
true);
367 return setValue(nPos1, nPos2,
false);
371 mrSegs(rSegs), mnCurPos(0), mnLastPos(-1), mbCurValue(false)
377 if (
nPos >= mnCurPos)
381 if (mnCurPos > mnLastPos)
385 if (!mrSegs.getRangeData(mnCurPos,
aData))
388 mbCurValue =
aData.mbValue;
389 mnLastPos =
aData.mnRow2;
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);
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);
451 ScFlatBoolSegmentsImpl::RangeData
aData;
455 rData.mbValue =
aData.mnValue;
456 rData.mnRow1 =
static_cast<SCROW>(
aData.mnPos1);
457 rData.mnRow2 =
static_cast<SCROW>(
aData.mnPos2);
463 ScFlatBoolSegmentsImpl::RangeData
aData;
467 rData.mbValue =
aData.mnValue;
468 rData.mnRow1 =
static_cast<SCROW>(
aData.mnPos1);
469 rData.mnRow2 =
static_cast<SCROW>(
aData.mnPos2);
485 return mpImpl->findLastTrue(
false);
502 aSegment = (aRange.mbValue ? std::string_view(
"1") : std::string_view(
"0")) + OString::Concat(
":");
506 aSegment += OString::number(aRange.mnRow2) +
" ";
540 ScFlatBoolSegmentsImpl::RangeData
aData;
544 rData.mbValue =
aData.mnValue;
545 rData.mnCol1 =
static_cast<SCCOL>(
aData.mnPos1);
546 rData.mnCol2 =
static_cast<SCCOL>(
aData.mnPos2);
574 aSegment = (aRange.mbValue ? OString::Concat(
"1") : OString::Concat(
"0")) + OString::Concat(
":");
578 aSegment += OString::number(aRange.mnCol2) +
" ";
587 mrSegs(rSegs), mnCurPos(0), mnLastPos(-1), mnCurValue(0)
593 if (
nPos >= mnCurPos)
597 if (mnCurPos > mnLastPos)
600 ScFlatUInt16SegmentsImpl::RangeData
aData;
604 if (!mrSegs.mpImpl->getRangeData(mnCurPos,
aData))
611 if (!mrSegs.mpImpl->getRangeDataLeaf(mnCurPos,
aData))
615 mnCurValue =
aData.mnValue;
616 mnLastPos =
aData.mnPos2;
654 ScFlatUInt16SegmentsImpl::RangeData
aData;
658 rData.mnRow1 =
aData.mnPos1;
659 rData.mnRow2 =
aData.mnPos2;
660 rData.mnValue =
aData.mnValue;
681 mpImpl->enableTreeSearch(bEnable);
702 aSegment = OString::number(aRange.mnValue) +
":" +
703 OString::number(aRange.mnRow2) +
" ";
void removeSegment(SCCOL nCol1, SCCOL nCol2)
bool setFalse(SCCOL nCol1, SCCOL nCol2)
bool setTrue(SCCOL nCol1, SCCOL nCol2)
bool getRangeData(SCCOL nCol, RangeData &rData)
::std::unique_ptr< ScFlatBoolSegmentsImpl > mpImpl
void insertSegment(SCCOL nCol, SCCOL nSize)
ScFlatBoolColSegments(SCCOL nMaxCol)
ForwardIterator(ScFlatBoolRowSegments &rSegs)
bool getValue(SCROW nPos, bool &rVal)
RangeIterator(ScFlatBoolRowSegments const &rSegs)
bool getFirst(RangeData &rRange)
bool getNext(RangeData &rRange)
void removeSegment(SCROW nRow1, SCROW nRow2)
void insertSegment(SCROW nRow, SCROW nSize)
bool setFalse(SCROW nRow1, SCROW nRow2)
ScFlatBoolRowSegments(SCROW nMaxRow)
bool setTrue(SCROW nRow1, SCROW nRow2)
bool getRangeDataLeaf(SCROW nRow, RangeData &rData)
SCROW findLastTrue() const
bool getRangeData(SCROW nRow, RangeData &rData) const
::std::unique_ptr< ScFlatBoolSegmentsImpl > mpImpl
ScFlatBoolSegmentsImpl(SCCOLROW nMax)
bool setTrue(SCCOLROW nPos1, SCCOLROW nPos2)
bool setFalse(SCCOLROW nPos1, SCCOLROW nPos2)
ForwardIterator(ScFlatUInt16RowSegments &rSegs)
bool getValue(SCROW nPos, sal_uInt16 &rVal)
bool getRangeData(SCROW nRow, RangeData &rData)
void setValueIf(SCROW nRow1, SCROW nRow2, sal_uInt16 nValue, const std::function< bool(sal_uInt16)> &rPredicate)
~ScFlatUInt16RowSegments()
void enableTreeSearch(bool bEnable)
sal_uInt16 getValue(SCROW nRow)
sal_uInt64 getSumValue(SCROW nRow1, SCROW nRow2)
::std::unique_ptr< ScFlatUInt16SegmentsImpl > mpImpl
void removeSegment(SCROW nRow1, SCROW nRow2)
void insertSegment(SCROW nRow, SCROW nSize)
SCROW findLastTrue(sal_uInt16 nValue) const
ScFlatUInt16RowSegments(SCROW nMaxRow, sal_uInt16 nDefault)
void setValue(SCROW nRow1, SCROW nRow2, sal_uInt16 nValue)
ScFlatUInt16SegmentsImpl(SCCOLROW nMax, sal_uInt16 nDefault)
static SC_DLLPUBLIC bool bThreadedGroupCalcInProgress
Calc's threaded group calculation is in progress.
#define SAL_WARN(area, stream)
constexpr OUStringLiteral aData
css::beans::Optional< css::uno::Any > getValue(std::u16string_view id)
constexpr T saturating_add(T a, T b)
RegError REGISTRY_CALLTYPE setValue(RegKeyHandle hKey, rtl_uString *keyName, RegValueType valueType, RegValue pData, sal_uInt32 valueSize)
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW