diff options
author | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2016-03-22 12:30:18 +0100 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2016-03-23 19:07:08 +0000 |
commit | 5c8991813dc303c7ffc8fef7d8d8f0779657fde6 (patch) | |
tree | 77fe400b8d6bbb030834d921148d8bef92a25e90 | |
parent | 8e9658b43153f20f644c053cf7ffe5c7883dd14d (diff) |
better use mdds in matrix concat, tdf#88849
Change-Id: I6155b86d0afbefafdf982962ffd0216334834379
Reviewed-on: https://gerrit.libreoffice.org/23425
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
-rw-r--r-- | sc/inc/scmatrix.hxx | 9 | ||||
-rw-r--r-- | sc/source/core/tool/interpr5.cxx | 18 | ||||
-rw-r--r-- | sc/source/core/tool/scmatrix.cxx | 118 |
3 files changed, 128 insertions, 17 deletions
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index d82cfa4ff66f..c8d4bcc5c3f9 100644 --- a/sc/inc/scmatrix.hxx +++ b/sc/inc/scmatrix.hxx @@ -406,6 +406,9 @@ public: virtual void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, const std::pair<size_t, size_t>& rEndPos, DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const = 0; + virtual void MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef& xMat1, const ScMatrixRef& xMat2, + SvNumberFormatter& rFormatter) = 0; + #if DEBUG_MATRIX virtual void Dump() const = 0; #endif @@ -615,6 +618,9 @@ public: DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const override; ScFullMatrix& operator+= ( const ScFullMatrix& r ); + virtual void MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef& xMat1, const ScMatrixRef& xMat2, + SvNumberFormatter& rFormatter) override; + #if DEBUG_MATRIX virtual void Dump() const override; #endif @@ -826,6 +832,9 @@ public: ScVectorRefMatrix& operator+=(const ScVectorRefMatrix& r); + virtual void MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef& xMat1, const ScMatrixRef& xMat2, + SvNumberFormatter& rFormatter) override; + #if DEBUG_MATRIX virtual void Dump() const override { diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx index 22a83758cac3..f7da2e7f7a6e 100644 --- a/sc/source/core/tool/interpr5.cxx +++ b/sc/source/core/tool/interpr5.cxx @@ -1170,23 +1170,7 @@ ScMatrixRef ScInterpreter::MatConcat(const ScMatrixRef& pMat1, const ScMatrixRef ScMatrixRef xResMat = GetNewMat(nMinC, nMinR); if (xResMat) { - for (SCSIZE i = 0; i < nMinC; i++) - { - for (SCSIZE j = 0; j < nMinR; j++) - { - sal_uInt16 nErr = pMat1->GetErrorIfNotString( i, j); - if (!nErr) - nErr = pMat2->GetErrorIfNotString( i, j); - if (nErr) - xResMat->PutError( nErr, i, j); - else - { - OUString aTmp = pMat1->GetString(*pFormatter, i, j).getString(); - aTmp += pMat2->GetString(*pFormatter, i, j).getString(); - xResMat->PutString(mrStrPool.intern(aTmp), i, j); - } - } - } + xResMat->MatConcat(nMinC, nMinR, pMat1, pMat2, *pFormatter); } return xResMat; } diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index 1feb7d4fe484..29905f365521 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -306,6 +306,9 @@ public: template<typename T> std::vector<ScMatrix::IterateResult> ApplyCollectOperation(bool bTextAsZero, const std::vector<std::unique_ptr<T>>& aOp); + void MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef& xMat1, const ScMatrixRef& xMat2, + SvNumberFormatter& rFormatter); + #if DEBUG_MATRIX void Dump() const; #endif @@ -2370,6 +2373,108 @@ void ScMatrixImpl::CalcPosition(SCSIZE nIndex, SCSIZE& rC, SCSIZE& rR) const rR = nIndex - rC*nRowSize; } +void ScMatrixImpl::MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef& xMat1, const ScMatrixRef& xMat2, + SvNumberFormatter& rFormatter) +{ + SCSIZE nC1, nC2; + SCSIZE nR1, nR2; + xMat1->GetDimensions(nC1, nR1); + xMat2->GetDimensions(nC2, nR2); + + sal_uLong nKey = rFormatter.GetStandardFormat( css::util::NumberFormat::NUMBER, + ScGlobal::eLnge); + + std::vector<OUString> aString(nMaxCol * nMaxRow); + std::vector<bool> aValid(nMaxCol * nMaxRow, true); + std::vector<sal_uInt16> nErrors(nMaxCol * nMaxRow, 0); + + size_t nRowOffset = 0; + size_t nColOffset = 0; + std::function<void(size_t, size_t, double)> aDoubleFunc = + [&](size_t nRow, size_t nCol, double nVal) + { + sal_uInt16 nErr = GetDoubleErrorValue(nVal); + if (nErr) + { + aValid[nMaxCol * (nRow + nRowOffset) + nCol + nColOffset] = false; + nErrors[nMaxCol * (nRow + nRowOffset) + nCol + nColOffset] = nErr; + return; + } + OUString aStr; + rFormatter.GetInputLineString( nVal, nKey, aStr); + aString[nMaxCol * (nRow + nRowOffset) + nCol + nColOffset] = aString[nMaxCol * (nRow + nRowOffset) + nCol + nColOffset] + aStr; + }; + + std::function<void(size_t, size_t, bool)> aBoolFunc = + [&](size_t nRow, size_t nCol, double nVal) + { + OUString aStr; + rFormatter.GetInputLineString( nVal, nKey, aStr); + aString[nMaxCol * (nRow + nRowOffset) + nCol + nColOffset] = aString[nMaxCol * (nRow + nRowOffset) + nCol + nColOffset] + aStr; + }; + + std::function<void(size_t, size_t, svl::SharedString)> aStringFunc = + [&](size_t nRow, size_t nCol, svl::SharedString aStr) + { + aString[(nRow + nRowOffset) * nMaxCol + nCol + nColOffset] = aString[(nRow + nRowOffset) * nMaxCol + nCol + nColOffset] + aStr.getString(); + }; + + if (nC1 == 1 || nR1 == 1) + { + size_t nRowRep = nR1 == 1 ? nMaxRow : 1; + size_t nColRep = nC1 == 1 ? nMaxCol : 1; + + for (size_t i = 0; i < nRowRep; ++i) + { + nRowOffset = i; + for (size_t j = 0; j < nColRep; ++j) + { + nColOffset = j; + xMat1->ExecuteOperation(std::pair<size_t, size_t>(0, 0), std::pair<size_t, size_t>(std::min(nR1, nMaxRow) - 1, std::min(nC1, nMaxCol) - 1), aDoubleFunc, aBoolFunc, aStringFunc); + } + } + } + else + xMat1->ExecuteOperation(std::pair<size_t, size_t>(0, 0), std::pair<size_t, size_t>(nMaxRow - 1, nMaxCol - 1), aDoubleFunc, aBoolFunc, aStringFunc); + + nRowOffset = 0; + nColOffset = 0; + if (nC2 == 1 || nR2 == 1) + { + size_t nRowRep = nR2 == 1 ? nMaxRow : 1; + size_t nColRep = nC2 == 1 ? nMaxCol : 1; + + for (size_t i = 0; i < nRowRep; ++i) + { + nRowOffset = i; + for (size_t j = 0; j < nColRep; ++j) + { + nColOffset = j; + xMat2->ExecuteOperation(std::pair<size_t, size_t>(0, 0), std::pair<size_t, size_t>(std::min(nR2, nMaxRow) - 1, std::min(nC2, nMaxCol) - 1), aDoubleFunc, aBoolFunc, aStringFunc); + } + } + } + else + xMat2->ExecuteOperation(std::pair<size_t, size_t>(0, 0), std::pair<size_t, size_t>(nMaxRow - 1, nMaxCol - 1), aDoubleFunc, aBoolFunc, aStringFunc); + + MatrixImplType::position_type pos = maMat.position(0, 0); + for (SCSIZE i = 0; i < nMaxCol; ++i) + { + for (SCSIZE j = 0; j < nMaxRow; ++j) + { + if (aValid[nMaxCol * j + i]) + { + pos = maMat.set(pos, aString[nMaxCol * j + i]); + } + else + { + pos = maMat.set(pos, CreateDoubleError(nErrors[nMaxCol * j + i])); + } + pos = maMat.next_position(pos); + } + } +} + void ScMatrix::IncRef() const { ++nRefCnt; @@ -3751,4 +3856,17 @@ void ScVectorRefMatrix::ExecuteOperation(const std::pair<size_t, size_t>& rStart mpFullMatrix->ExecuteOperation(rStartPos, rEndPos, aDoubleFunc, aBoolFunc, aStringFunc); } +void ScFullMatrix::MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, + const ScMatrixRef& xMat1, const ScMatrixRef& xMat2, SvNumberFormatter& rFormatter) +{ + pImpl->MatConcat(nMaxCol, nMaxRow, xMat1, xMat2, rFormatter); +} + +void ScVectorRefMatrix::MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, + const ScMatrixRef& xMat1, const ScMatrixRef& xMat2, SvNumberFormatter& rFormatter) +{ + ensureFullMatrix(); + mpFullMatrix->MatConcat(nMaxCol, nMaxRow, xMat1, xMat2, rFormatter); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |