sc/inc/calcconfig.hxx | 1 sc/inc/scmatrix.hxx | 587 +++++++++++++++++++---- sc/qa/unit/ucalc.cxx | 16 sc/source/core/data/table1.cxx | 2 sc/source/core/data/validat.cxx | 2 sc/source/core/inc/arraysumfunctor.hxx | 1 sc/source/core/tool/addincol.cxx | 6 sc/source/core/tool/calcconfig.cxx | 11 sc/source/core/tool/ddelink.cxx | 4 sc/source/core/tool/formulagroup.cxx | 80 +-- sc/source/core/tool/interpr1.cxx | 6 sc/source/core/tool/interpr5.cxx | 10 sc/source/core/tool/jumpmatrix.cxx | 2 sc/source/core/tool/rangeseq.cxx | 2 sc/source/core/tool/scmatrix.cxx | 695 +++++++++++++++++++++++----- sc/source/core/tool/token.cxx | 18 sc/source/filter/excel/tokstack.cxx | 2 sc/source/filter/excel/xihelper.cxx | 2 sc/source/filter/excel/xilink.cxx | 2 sc/source/filter/inc/xihelper.hxx | 2 sc/source/filter/xml/XMLDDELinksContext.cxx | 2 sc/source/filter/xml/xmlcelli.cxx | 2 sc/source/ui/docshell/externalrefmgr.cxx | 6 23 files changed, 1180 insertions(+), 281 deletions(-)
New commits: commit a81de86c47322bd6bc59b462eb2f69e0f1185df4 Author: Jan Holesovsky <ke...@collabora.com> Date: Tue Nov 24 17:13:21 2015 +0100 sc: Implement Software Interpreter subsetting, similarly to openCL one. And add only the minimum amount of operations we are sure about. Change-Id: I0dd35968206161e31fcd8bfd0b647329c703e0da diff --git a/sc/inc/calcconfig.hxx b/sc/inc/calcconfig.hxx index 4091bda..ec355cf 100644 --- a/sc/inc/calcconfig.hxx +++ b/sc/inc/calcconfig.hxx @@ -58,6 +58,7 @@ struct SC_DLLPUBLIC ScCalcConfig typedef std::shared_ptr<std::set<OpCode>> OpCodeSet; OpCodeSet mpOpenCLSubsetOpCodes; + OpCodeSet mpSwInterpreterSubsetOpCodes; ScCalcConfig(); diff --git a/sc/source/core/tool/calcconfig.cxx b/sc/source/core/tool/calcconfig.cxx index 20d5530..f285e13 100644 --- a/sc/source/core/tool/calcconfig.cxx +++ b/sc/source/core/tool/calcconfig.cxx @@ -86,6 +86,15 @@ void ScCalcConfig::setOpenCLConfigToDefault() ocSlope, ocSumIfs})); + // opcodes that are known to work well with the software interpreter + static OpCodeSet pDefaultSwInterpreterSubsetOpCodes(new std::set<OpCode>({ + ocAdd, + ocSub, + ocMul, + ocDiv, + ocSum, + ocProduct})); + // Note that these defaults better be kept in sync with those in // officecfg/registry/schema/org/openoffice/Office/Calc.xcs. // Crazy. @@ -93,6 +102,7 @@ void ScCalcConfig::setOpenCLConfigToDefault() mbOpenCLAutoSelect = true; mnOpenCLMinimumFormulaGroupSize = 100; mpOpenCLSubsetOpCodes = pDefaultOpenCLSubsetOpCodes; + mpSwInterpreterSubsetOpCodes = pDefaultSwInterpreterSubsetOpCodes; } void ScCalcConfig::reset() @@ -127,6 +137,7 @@ bool ScCalcConfig::operator== (const ScCalcConfig& r) const maOpenCLDevice == r.maOpenCLDevice && mnOpenCLMinimumFormulaGroupSize == r.mnOpenCLMinimumFormulaGroupSize && *mpOpenCLSubsetOpCodes == *r.mpOpenCLSubsetOpCodes && + *mpSwInterpreterSubsetOpCodes == *r.mpSwInterpreterSubsetOpCodes && true; } diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 3f978c4..138e087 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -1319,6 +1319,12 @@ void ScTokenArray::CheckToken( const FormulaToken& r ) return; } + if (!ScCalcConfig::isOpenCLEnabled() && getenv("SC_ALLOW_SOFTWARE_INTERPRETER") != nullptr && ScInterpreter::GetGlobalConfig().mpSwInterpreterSubsetOpCodes->find(eOp) == ScInterpreter::GetGlobalConfig().mpSwInterpreterSubsetOpCodes->end()) + { + meVectorState = FormulaVectorDisabled; + return; + } + // We support vectorization for the following opcodes. switch (eOp) { @@ -1559,6 +1565,16 @@ void ScTokenArray::CheckToken( const FormulaToken& r ) meVectorState = FormulaVectorDisabled; return; } + + if (eOp >= SC_OPCODE_START_BIN_OP && + eOp <= SC_OPCODE_STOP_UN_OP && + !ScCalcConfig::isOpenCLEnabled() && + getenv("SC_ALLOW_SOFTWARE_INTERPRETER") != nullptr && + ScInterpreter::GetGlobalConfig().mpSwInterpreterSubsetOpCodes->find(eOp) == ScInterpreter::GetGlobalConfig().mpSwInterpreterSubsetOpCodes->end()) + { + meVectorState = FormulaVectorDisabled; + return; + } } bool ScTokenArray::ImplGetReference( ScRange& rRange, const ScAddress& rPos, bool bValidOnly ) const commit 8e148863d9683b8b73b28818d144330a607fb511 Author: Jan Holesovsky <ke...@collabora.com> Date: Tue Nov 24 10:27:03 2015 +0100 sc: Implement ScVectorRefMatrix. This is a ScMatrix implementation that operates directly on formula::DoubleVectorRefToken, saving tremendous amount of copying data back and forth. Change-Id: I027e6cb668ef40eb474773a0ce8d0eeefc1ab71c diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index 1f5d438..7f1392b 100644 --- a/sc/inc/scmatrix.hxx +++ b/sc/inc/scmatrix.hxx @@ -40,6 +40,8 @@ class ScInterpreter; class SvNumberFormatter; class ScMatrixImpl; +namespace formula { class DoubleVectorRefToken; } + namespace sc { struct Compare; @@ -106,7 +108,7 @@ struct ScMatrixValue } }; -/// Abstract base class for ScFullMatrix and ScSubMatrix implementations. +/// Abstract base class for ScFullMatrix and ScVectorRefMatrix implementations. class SC_DLLPUBLIC ScMatrix { mutable size_t nRefCnt; // reference count @@ -604,6 +606,202 @@ public: #endif }; +class SC_DLLPUBLIC ScVectorRefMatrix : public ScMatrix +{ + const formula::DoubleVectorRefToken* mpToken; + ScInterpreter* mpErrorInterpreter; + + SCSIZE mnRowStart; + SCSIZE mnRowSize; + + // only delete via Delete() + virtual ~ScVectorRefMatrix(); + + ScVectorRefMatrix( const ScVectorRefMatrix& ) = delete; + ScVectorRefMatrix& operator=( const ScVectorRefMatrix&) = delete; + +public: + + ScVectorRefMatrix(const formula::DoubleVectorRefToken* pToken, SCSIZE nRowStart, SCSIZE nRowSize); + + /** Clone the matrix. */ + virtual ScMatrix* Clone() const override; + + /** + * Resize the matrix to specified new dimension. + */ + virtual void Resize(SCSIZE nC, SCSIZE nR) override; + + virtual void Resize(SCSIZE nC, SCSIZE nR, double fVal) override; + + /** Clone the matrix and extend it to the new size. nNewCols and nNewRows + MUST be at least of the size of the original matrix. */ + virtual ScMatrix* CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const override; + + virtual void SetErrorInterpreter(ScInterpreter* p) override; + virtual void GetDimensions(SCSIZE& rC, SCSIZE& rR) const override; + virtual SCSIZE GetElementCount() const override; + virtual bool ValidColRow( SCSIZE nC, SCSIZE nR) const override; + + /** For a row vector or column vector, if the position does not point into + the vector but is a valid column or row offset it is adapted such that + it points to an element to be replicated, same column row 0 for a row + vector, same row column 0 for a column vector. Else, for a 2D matrix, + returns false. + */ + virtual bool ValidColRowReplicated(SCSIZE & rC, SCSIZE & rR) const override; + + /** Checks if the matrix position is within the matrix. If it is not, for a + row vector or column vector the position is adapted such that it points + to an element to be replicated, same column row 0 for a row vector, + same row column 0 for a column vector. Else, for a 2D matrix and + position not within matrix, returns false. + */ + virtual bool ValidColRowOrReplicated(SCSIZE & rC, SCSIZE & rR) const override; + + virtual void PutDouble(double fVal, SCSIZE nC, SCSIZE nR) override; + virtual void PutDouble(double fVal, SCSIZE nIndex) override; + virtual void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) override; + + virtual void PutString(const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR) override; + virtual void PutString(const svl::SharedString& rStr, SCSIZE nIndex) override; + virtual void PutString(const svl::SharedString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) override; + + virtual void PutEmpty(SCSIZE nC, SCSIZE nR) override; + + /// Jump sal_False without path + virtual void PutEmptyPath(SCSIZE nC, SCSIZE nR) override; + virtual void PutError(sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR ) override; + virtual void PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR) override; + + virtual void FillDouble(double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2) override; + + /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */ + virtual void PutDoubleVector(const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR) override; + + /** Put a column vector of strings, starting at row nR, must fit into dimensions. */ + virtual void PutStringVector(const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR) override; + + /** Put a column vector of empties, starting at row nR, must fit into dimensions. */ + virtual void PutEmptyVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR) override; + + /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */ + virtual void PutEmptyResultVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR) override; + + /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */ + virtual void PutEmptyPathVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR) override; + + /** May be used before obtaining the double value of an element to avoid + passing its NAN around. + @ATTENTION: MUST NOT be used if the element is a string! + Use GetErrorIfNotString() instead if not sure. + @returns 0 if no error, else one of err... constants */ + virtual sal_uInt16 GetError(SCSIZE nC, SCSIZE nR) const override; + + /// @return 0.0 if empty or empty path, else value or DoubleError. + virtual double GetDouble(SCSIZE nC, SCSIZE nR) const override; + /// @return 0.0 if empty or empty path, else value or DoubleError. + virtual double GetDouble(SCSIZE nIndex) const override; + + /// @return empty string if empty or empty path, else string content. + virtual svl::SharedString GetString(SCSIZE nC, SCSIZE nR) const override; + /// @return empty string if empty or empty path, else string content. + virtual svl::SharedString GetString(SCSIZE nIndex) const override; + + /** @returns the matrix element's string if one is present, otherwise the + numerical value formatted as string, or in case of an error the error + string is returned; an empty string for empty, a "FALSE" string for + empty path. */ + virtual svl::SharedString GetString(SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const override; + + /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate + /// an empty string! + virtual ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const override; + + /// @return <TRUE/> if string or empty or empty path, in fact non-value. + virtual bool IsString(SCSIZE nIndex) const override; + + /// @return <TRUE/> if string or empty or empty path, in fact non-value. + virtual bool IsString(SCSIZE nC, SCSIZE nR) const override; + + /// @return <TRUE/> if empty or empty cell or empty result, not empty path. + virtual bool IsEmpty(SCSIZE nC, SCSIZE nR) const override; + + /// @return <TRUE/> if empty cell, not empty or empty result or empty path. + virtual bool IsEmptyCell(SCSIZE nC, SCSIZE nR) const override; + + /// @return <TRUE/> if empty result, not empty or empty cell or empty path. + virtual bool IsEmptyResult(SCSIZE nC, SCSIZE nR) const override; + + /// @return <TRUE/> if empty path, not empty or empty cell or empty result. + virtual bool IsEmptyPath(SCSIZE nC, SCSIZE nR) const override; + + /// @return <TRUE/> if value or boolean. + virtual bool IsValue(SCSIZE nIndex) const override; + + /// @return <TRUE/> if value or boolean. + virtual bool IsValue(SCSIZE nC, SCSIZE nR) const override; + + /// @return <TRUE/> if value or boolean or empty or empty path. + virtual bool IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const override; + + /// @return <TRUE/> if boolean. + virtual bool IsBoolean(SCSIZE nC, SCSIZE nR) const override; + + /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties + virtual bool IsNumeric() const override; + + virtual void MatTrans(ScMatrix& mRes) const override; + virtual void MatCopy (ScMatrix& mRes) const override; + + // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values + virtual void CompareEqual() override; + virtual void CompareNotEqual() override; + virtual void CompareLess() override; + virtual void CompareGreater() override; + virtual void CompareLessEqual() override; + virtual void CompareGreaterEqual() override; + + virtual double And() const override; // logical AND of all matrix values, or NAN + virtual double Or() const override; // logical OR of all matrix values, or NAN + virtual double Xor() const override; // logical XOR of all matrix values, or NAN + + virtual IterateResult Sum(bool bTextAsZero) const override; + virtual IterateResult SumSquare(bool bTextAsZero) const override; + virtual IterateResult Product(bool bTextAsZero) const override; + virtual size_t Count(bool bCountStrings) const override; + virtual size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const override; + virtual size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const override; + + virtual double GetMaxValue(bool bTextAsZero) const override; + virtual double GetMinValue(bool bTextAsZero) const override; + + virtual ScMatrixRef CompareMatrix(sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions = nullptr) const override; + + /** + * Convert the content of matrix into a linear array of numeric values. + * String elements are mapped to NaN's and empty elements are mapped to + * either NaN or zero values. + * + * @param bEmptyAsZero if true empty elements are mapped to zero values, + * otherwise they become NaN values. + */ + virtual void GetDoubleArray(std::vector<double>& rVector, bool bEmptyAsZero = true) const override; + virtual void MergeDoubleArray(std::vector<double>& rVector, Op eOp) const override; + + virtual void NotOp(ScMatrix& rMat) override; + virtual void NegOp(ScMatrix& rMat) override; + virtual void AddOp(double fVal, ScMatrix& rMat) override; + virtual void SubOp(bool bFlag, double fVal, ScMatrix& rMat) override; + virtual void MulOp(double fVal, ScMatrix& rMat) override; + virtual void DivOp(bool bFlag, double fVal, ScMatrix& rMat) override; + virtual void PowOp(bool bFlag, double fVal, ScMatrix& rMat) override; + + virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) override; + + ScVectorRefMatrix& operator+=(const ScVectorRefMatrix& r); +}; + inline void intrusive_ptr_add_ref(const ScMatrix* p) { p->IncRef(); diff --git a/sc/source/core/inc/arraysumfunctor.hxx b/sc/source/core/inc/arraysumfunctor.hxx index e9ef404..200fdc6 100644 --- a/sc/source/core/inc/arraysumfunctor.hxx +++ b/sc/source/core/inc/arraysumfunctor.hxx @@ -11,6 +11,7 @@ #ifndef INCLUDED_SC_SOURCE_CORE_INC_ARRAYSUMFUNCTOR_HXX #define INCLUDED_SC_SOURCE_CORE_INC_ARRAYSUMFUNCTOR_HXX +#include <cstdint> #include <tools/cpuid.hxx> #if defined(LO_SSE2_AVAILABLE) diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx index a9f8a61..c4abe00 100644 --- a/sc/source/core/tool/formulagroup.cxx +++ b/sc/source/core/tool/formulagroup.cxx @@ -369,52 +369,62 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres case formula::svDoubleVectorRef: { const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p); - const std::vector<formula::VectorRefArray>& rArrays = p2->GetArrays(); - size_t nColSize = rArrays.size(); size_t nRowStart = p2->IsStartFixed() ? 0 : i; size_t nRowEnd = p2->GetRefRowSize() - 1; if (!p2->IsEndFixed()) nRowEnd += i; - size_t nRowSize = nRowEnd - nRowStart + 1; - ScMatrixRef pMat(new ScFullMatrix(nColSize, nRowSize)); - - size_t nDataRowEnd = p2->GetArrayLength() - 1; - if (nRowStart > nDataRowEnd) - // Referenced rows are all empty. - nRowSize = 0; - else if (nRowEnd > nDataRowEnd) - // Data array is shorter than the row size of the reference. Truncate it to the data. - nRowSize -= nRowEnd - nDataRowEnd; - - for (size_t nCol = 0; nCol < nColSize; ++nCol) + + ScMatrixRef pMat; + if (getenv("SC_ALLOW_SOFTWARE_INTERPRETER") != nullptr) { - const formula::VectorRefArray& rArray = rArrays[nCol]; - if (rArray.mpStringArray) + assert(nRowStart <= nRowEnd); + pMat.reset(new ScVectorRefMatrix(p2, nRowStart, nRowEnd - nRowStart + 1)); + } + else + { + const std::vector<formula::VectorRefArray>& rArrays = p2->GetArrays(); + size_t nColSize = rArrays.size(); + size_t nRowSize = nRowEnd - nRowStart + 1; + pMat.reset(new ScFullMatrix(nColSize, nRowSize)); + + size_t nDataRowEnd = p2->GetArrayLength() - 1; + if (nRowStart > nDataRowEnd) + // Referenced rows are all empty. + nRowSize = 0; + else if (nRowEnd > nDataRowEnd) + // Data array is shorter than the row size of the reference. Truncate it to the data. + nRowSize -= nRowEnd - nDataRowEnd; + + for (size_t nCol = 0; nCol < nColSize; ++nCol) { - if (rArray.mpNumericArray) + const formula::VectorRefArray& rArray = rArrays[nCol]; + if (rArray.mpStringArray) { - // Mixture of string and numeric values. - const double* pNums = rArray.mpNumericArray; - pNums += nRowStart; - rtl_uString** pStrs = rArray.mpStringArray; - pStrs += nRowStart; - fillMatrix(*pMat, nCol, pNums, pStrs, nRowSize); + if (rArray.mpNumericArray) + { + // Mixture of string and numeric values. + const double* pNums = rArray.mpNumericArray; + pNums += nRowStart; + rtl_uString** pStrs = rArray.mpStringArray; + pStrs += nRowStart; + fillMatrix(*pMat, nCol, pNums, pStrs, nRowSize); + } + else + { + // String cells only. + rtl_uString** pStrs = rArray.mpStringArray; + pStrs += nRowStart; + fillMatrix(*pMat, nCol, pStrs, nRowSize); + } } - else + else if (rArray.mpNumericArray) { - // String cells only. - rtl_uString** pStrs = rArray.mpStringArray; - pStrs += nRowStart; - fillMatrix(*pMat, nCol, pStrs, nRowSize); + // Numeric cells only. + const double* pNums = rArray.mpNumericArray; + pNums += nRowStart; + fillMatrix(*pMat, nCol, pNums, nRowSize); } } - else if (rArray.mpNumericArray) - { - // Numeric cells only. - const double* pNums = rArray.mpNumericArray; - pNums += nRowStart; - fillMatrix(*pMat, nCol, pNums, nRowSize); - } } if (p2->IsStartFixed() && p2->IsEndFixed()) diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index e3823bd..cb242ca 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -17,10 +17,12 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <arraysumfunctor.hxx> #include "scmatrix.hxx" #include "global.hxx" #include "address.hxx" #include <formula/errorcodes.hxx> +#include <formula/vectortoken.hxx> #include "interpre.hxx" #include "mtvelements.hxx" #include "compare.hxx" @@ -279,9 +281,9 @@ public: double Or() const; double Xor() const; - ScFullMatrix::IterateResult Sum(bool bTextAsZero) const; - ScFullMatrix::IterateResult SumSquare(bool bTextAsZero) const; - ScFullMatrix::IterateResult Product(bool bTextAsZero) const; + ScMatrix::IterateResult Sum(bool bTextAsZero) const; + ScMatrix::IterateResult SumSquare(bool bTextAsZero) const; + ScMatrix::IterateResult Product(bool bTextAsZero) const; size_t Count(bool bCountStrings) const; size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const; size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const; @@ -299,7 +301,7 @@ public: void ApplyOperation(T aOp, ScMatrixImpl& rMat); template<typename T> - std::vector<ScFullMatrix::IterateResult> ApplyCollectOperation(bool bTextAsZero, const std::vector<std::unique_ptr<T>>& aOp); + std::vector<ScMatrix::IterateResult> ApplyCollectOperation(bool bTextAsZero, const std::vector<std::unique_ptr<T>>& aOp); #if DEBUG_MATRIX void Dump() const; @@ -999,13 +1001,13 @@ template<typename _Op> class WalkElementBlocks { _Op maOp; - ScFullMatrix::IterateResult maRes; + ScMatrix::IterateResult maRes; bool mbFirst:1; bool mbTextAsZero:1; public: WalkElementBlocks(bool bTextAsZero) : maRes(_Op::InitVal, _Op::InitVal, 0), mbFirst(true), mbTextAsZero(bTextAsZero) {} - const ScFullMatrix::IterateResult& getResult() const { return maRes; } + const ScMatrix::IterateResult& getResult() const { return maRes; } void operator() (const MatrixImplType::element_block_node_type& node) { @@ -1068,7 +1070,7 @@ template<typename _Op> class WalkElementBlocksMultipleValues { const std::vector<std::unique_ptr<_Op>>& maOp; - std::vector<ScFullMatrix::IterateResult> maRes; + std::vector<ScMatrix::IterateResult> maRes; bool mbFirst:1; bool mbTextAsZero:1; public: @@ -1082,7 +1084,7 @@ public: maRes.emplace_back(0.0, 0.0, 0); // count } - const std::vector<ScFullMatrix::IterateResult>& getResult() const { return maRes; } + const std::vector<ScMatrix::IterateResult>& getResult() const { return maRes; } void operator() (const MatrixImplType::element_block_node_type& node) { @@ -1752,7 +1754,7 @@ public: namespace { template<typename TOp> -ScFullMatrix::IterateResult GetValueWithCount(bool bTextAsZero, const MatrixImplType& maMat) +ScMatrix::IterateResult GetValueWithCount(bool bTextAsZero, const MatrixImplType& maMat) { WalkElementBlocks<TOp> aFunc(bTextAsZero); maMat.walk(aFunc); @@ -1761,17 +1763,17 @@ ScFullMatrix::IterateResult GetValueWithCount(bool bTextAsZero, const MatrixImpl } -ScFullMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const +ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const { return GetValueWithCount<sc::op::Sum>(bTextAsZero, maMat); } -ScFullMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const +ScMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const { return GetValueWithCount<sc::op::SumSquare>(bTextAsZero, maMat); } -ScFullMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const +ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const { return GetValueWithCount<sc::op::Product>(bTextAsZero, maMat); } @@ -2160,7 +2162,7 @@ void ScMatrixImpl::ApplyOperation(T aOp, ScMatrixImpl& rMat) } template<typename T> -std::vector<ScFullMatrix::IterateResult> ScMatrixImpl::ApplyCollectOperation(bool bTextAsZero, const std::vector<std::unique_ptr<T>>& aOp) +std::vector<ScMatrix::IterateResult> ScMatrixImpl::ApplyCollectOperation(bool bTextAsZero, const std::vector<std::unique_ptr<T>>& aOp) { WalkElementBlocksMultipleValues<T> aFunc(bTextAsZero, aOp); maMat.walk(aFunc); @@ -2550,17 +2552,17 @@ double ScFullMatrix::Xor() const return pImpl->Xor(); } -ScFullMatrix::IterateResult ScFullMatrix::Sum(bool bTextAsZero) const +ScMatrix::IterateResult ScFullMatrix::Sum(bool bTextAsZero) const { return pImpl->Sum(bTextAsZero); } -ScFullMatrix::IterateResult ScFullMatrix::SumSquare(bool bTextAsZero) const +ScMatrix::IterateResult ScFullMatrix::SumSquare(bool bTextAsZero) const { return pImpl->SumSquare(bTextAsZero); } -ScFullMatrix::IterateResult ScFullMatrix::Product(bool bTextAsZero) const +ScMatrix::IterateResult ScFullMatrix::Product(bool bTextAsZero) const { return pImpl->Product(bTextAsZero); } @@ -2815,7 +2817,7 @@ void ScFullMatrix::PowOp( bool bFlag, double fVal, ScMatrix& rMat) } } -std::vector<ScFullMatrix::IterateResult> ScFullMatrix::Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) +std::vector<ScMatrix::IterateResult> ScFullMatrix::Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) { return pImpl->ApplyCollectOperation(bTextAsZero, aOp); } @@ -2833,4 +2835,436 @@ void ScFullMatrix::Dump() const } #endif +ScVectorRefMatrix::ScVectorRefMatrix(const formula::DoubleVectorRefToken* pToken, SCSIZE nRowStart, SCSIZE nRowSize) + : ScMatrix() + , mpToken(pToken) + , mnRowStart(nRowStart) + , mnRowSize(nRowSize) +{ +} + +ScVectorRefMatrix::~ScVectorRefMatrix() +{ +} + +ScMatrix* ScVectorRefMatrix::Clone() const +{ + throw std::runtime_error("ScVectorRefMatrix::Clone() called"); +} + +void ScVectorRefMatrix::Resize(SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::Resize called"); +} + +void ScVectorRefMatrix::Resize(SCSIZE nC, SCSIZE nR, double fVal) +{ + throw std::runtime_error("ScVectorRefMatrix::Resize called"); +} + +ScMatrix* ScVectorRefMatrix::CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const +{ + throw std::runtime_error("ScVectorRefMatrix::CloneAndExtend called"); +} + +void ScVectorRefMatrix::SetErrorInterpreter(ScInterpreter* p) +{ + mpErrorInterpreter = p; +} + +void ScVectorRefMatrix::GetDimensions(SCSIZE& rC, SCSIZE& rR) const +{ + rC = mpToken->GetArrays().size(); + rR = mnRowSize; +} + +SCSIZE ScVectorRefMatrix::GetElementCount() const +{ + throw std::runtime_error("ScVectorRefMatrix::GetElementCount called"); +} + +bool ScVectorRefMatrix::ValidColRow(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::ValidColRow called"); +} + +bool ScVectorRefMatrix::ValidColRowReplicated(SCSIZE & rC, SCSIZE & rR) const +{ + throw std::runtime_error("ScVectorRefMatrix::ValidColRowReplicated called"); +} + +bool ScVectorRefMatrix::ValidColRowOrReplicated(SCSIZE & rC, SCSIZE & rR) const +{ + throw std::runtime_error("ScVectorRefMatrix::ValidColRowOrReplicated called"); +} + +void ScVectorRefMatrix::PutDouble(double fVal, SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutDouble called"); +} + +void ScVectorRefMatrix::PutDouble(double fVal, SCSIZE nIndex) +{ + throw std::runtime_error("ScVectorRefMatrix::PutDouble called"); +} + +void ScVectorRefMatrix::PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutDouble called"); +} + +void ScVectorRefMatrix::PutString(const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutString called"); +} + +void ScVectorRefMatrix::PutString(const svl::SharedString& rStr, SCSIZE nIndex) +{ + throw std::runtime_error("ScVectorRefMatrix::PutString called"); +} + +void ScVectorRefMatrix::PutString(const svl::SharedString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutString called"); +} + +void ScVectorRefMatrix::PutEmpty(SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutEmpty called"); +} + +void ScVectorRefMatrix::PutEmptyPath(SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutEmptyPath called"); +} + +void ScVectorRefMatrix::PutError(sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutError called"); +} + +void ScVectorRefMatrix::PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutBoolean called"); +} + +void ScVectorRefMatrix::FillDouble(double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2) +{ + throw std::runtime_error("ScVectorRefMatrix::FillDouble called"); +} + +void ScVectorRefMatrix::PutDoubleVector(const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutDoubleVector called"); +} + +void ScVectorRefMatrix::PutStringVector(const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutStringVector called"); +} + +void ScVectorRefMatrix::PutEmptyVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutEmptyVector called"); +} + +void ScVectorRefMatrix::PutEmptyResultVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutEmptyResultVector called"); +} + +void ScVectorRefMatrix::PutEmptyPathVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR) +{ + throw std::runtime_error("ScVectorRefMatrix::PutEmptyPathVector called"); +} + +sal_uInt16 ScVectorRefMatrix::GetError(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::GetError called"); +} + +double ScVectorRefMatrix::GetDouble(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::GetDouble called"); +} + +double ScVectorRefMatrix::GetDouble(SCSIZE nIndex) const +{ + throw std::runtime_error("ScVectorRefMatrix::GetDouble called"); +} + +svl::SharedString ScVectorRefMatrix::GetString(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::GetString called"); +} + +svl::SharedString ScVectorRefMatrix::GetString(SCSIZE nIndex) const +{ + throw std::runtime_error("ScVectorRefMatrix::GetString called"); +} + +svl::SharedString ScVectorRefMatrix::GetString(SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::GetString called"); +} + +ScMatrixValue ScVectorRefMatrix::Get(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::Get called"); +} + +bool ScVectorRefMatrix::IsString(SCSIZE nIndex) const +{ + throw std::runtime_error("ScVectorRefMatrix::IsString called"); +} + +bool ScVectorRefMatrix::IsString(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::IsString called"); +} + +bool ScVectorRefMatrix::IsEmpty(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::IsEmpty called"); +} + +bool ScVectorRefMatrix::IsEmptyCell(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::IsEmptyCell called"); +} + +bool ScVectorRefMatrix::IsEmptyResult(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::IsEmptyResult called"); +} + +bool ScVectorRefMatrix::IsEmptyPath(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::IsEmptyPath called"); +} + +bool ScVectorRefMatrix::IsValue(SCSIZE nIndex) const +{ + throw std::runtime_error("ScVectorRefMatrix::IsValue called"); +} + +bool ScVectorRefMatrix::IsValue(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::IsValue called"); +} + +bool ScVectorRefMatrix::IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::IsValueOrEmpty called"); +} + +bool ScVectorRefMatrix::IsBoolean(SCSIZE nC, SCSIZE nR) const +{ + throw std::runtime_error("ScVectorRefMatrix::IsBoolean called"); +} + +bool ScVectorRefMatrix::IsNumeric() const +{ + throw std::runtime_error("ScVectorRefMatrix::IsNumeric called"); +} + +void ScVectorRefMatrix::MatTrans(ScMatrix& mRes) const +{ + throw std::runtime_error("ScVectorRefMatrix::MatTrans called"); +} + +void ScVectorRefMatrix::MatCopy(ScMatrix& mRes) const +{ + throw std::runtime_error("ScVectorRefMatrix::MatCopy called"); +} + +void ScVectorRefMatrix::CompareEqual() +{ + throw std::runtime_error("ScVectorRefMatrix::CompareEqual called"); +} + +void ScVectorRefMatrix::CompareNotEqual() +{ + throw std::runtime_error("ScVectorRefMatrix::CompareNotEqual called"); +} + +void ScVectorRefMatrix::CompareLess() +{ + throw std::runtime_error("ScVectorRefMatrix::CompareLess called"); +} + +void ScVectorRefMatrix::CompareGreater() +{ + throw std::runtime_error("ScVectorRefMatrix::CompareGreater called"); +} + +void ScVectorRefMatrix::CompareLessEqual() +{ + throw std::runtime_error("ScVectorRefMatrix::CompareLessEqual called"); +} + +void ScVectorRefMatrix::CompareGreaterEqual() +{ + throw std::runtime_error("ScVectorRefMatrix::CompareGreaterEqual called"); +} + +double ScVectorRefMatrix::And() const +{ + throw std::runtime_error("ScVectorRefMatrix::And called"); +} + +double ScVectorRefMatrix::Or() const +{ + throw std::runtime_error("ScVectorRefMatrix::Or called"); +} + +double ScVectorRefMatrix::Xor() const +{ + throw std::runtime_error("ScVectorRefMatrix::Xor called"); +} + +ScMatrix::IterateResult ScVectorRefMatrix::Sum(bool bTextAsZero) const +{ + const std::vector<formula::VectorRefArray>& rArrays = mpToken->GetArrays(); + size_t nDataSize = mnRowSize; + + if (mnRowStart >= mpToken->GetRefRowSize()) + { + return ScMatrix::IterateResult(0.0, 0.0, 0); + } + else if (nDataSize > mpToken->GetRefRowSize() + mnRowStart) + { + nDataSize = mpToken->GetRefRowSize() - mnRowStart; + } + + double mfFirst = 0.0; + double mfRest = 0.0; + for (const formula::VectorRefArray& rArray : rArrays) + { + if (rArray.mpStringArray) + { + // TODO FIXME + throw std::runtime_error("ScVectorRefMatrix::Sum - string array"); + } + else if (rArray.mpNumericArray) + { + // Numeric cells only. + const double* p = rArray.mpNumericArray + mnRowStart; + size_t i = 0; + + // Store the first non-zero value in mfFirst (for some reason). + if (!mfFirst) + { + for (i = 0; i < nDataSize; ++i) + { + if (!mfFirst) + mfFirst = p[i]; + else + break; + } + } + p += i; + nDataSize -= i; + if (nDataSize == 0) + continue; + + sc::ArraySumFunctor functor(p, nDataSize); + + mfRest += functor(); + } + } + + return ScMatrix::IterateResult(mfFirst, mfRest, mpToken->GetArrays().size()*nDataSize); +} + +ScMatrix::IterateResult ScVectorRefMatrix::SumSquare(bool bTextAsZero) const +{ + throw std::runtime_error("ScVectorRefMatrix::SumSquare called"); +} + +ScMatrix::IterateResult ScVectorRefMatrix::Product(bool bTextAsZero) const +{ + throw std::runtime_error("ScVectorRefMatrix::Product called"); +} + +size_t ScVectorRefMatrix::Count(bool bCountStrings) const +{ + throw std::runtime_error("ScVectorRefMatrix::Count called"); +} + +size_t ScVectorRefMatrix::MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const +{ + throw std::runtime_error("ScVectorRefMatrix::MatchDoubleInColumns called"); +} + +size_t ScVectorRefMatrix::MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const +{ + throw std::runtime_error("ScVectorRefMatrix::MatchStringInColumns called"); +} + +double ScVectorRefMatrix::GetMaxValue(bool bTextAsZero) const +{ + throw std::runtime_error("ScVectorRefMatrix::GetMaxValue called"); +} + +double ScVectorRefMatrix::GetMinValue(bool bTextAsZero) const +{ + throw std::runtime_error("ScVectorRefMatrix::GetMinValue called"); +} + +ScMatrixRef ScVectorRefMatrix::CompareMatrix(sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions) const +{ + throw std::runtime_error("ScVectorRefMatrix::CompareMatrix called"); +} + +void ScVectorRefMatrix::GetDoubleArray(std::vector<double>& rVector, bool bEmptyAsZero) const +{ + throw std::runtime_error("ScVectorRefMatrix::GetDoubleArray called"); +} + +void ScVectorRefMatrix::MergeDoubleArray(std::vector<double>& rVector, Op eOp) const +{ + throw std::runtime_error("ScVectorRefMatrix::MergeDoubleArray called"); +} + +void ScVectorRefMatrix::NotOp(ScMatrix& rMat) +{ + throw std::runtime_error("ScVectorRefMatrix::NotOp called"); +} + +void ScVectorRefMatrix::NegOp(ScMatrix& rMat) +{ + throw std::runtime_error("ScVectorRefMatrix::NegOp called"); +} + +void ScVectorRefMatrix::AddOp(double fVal, ScMatrix& rMat) +{ + throw std::runtime_error("ScVectorRefMatrix::AddOp called"); +} + +void ScVectorRefMatrix::SubOp(bool bFlag, double fVal, ScMatrix& rMat) +{ + throw std::runtime_error("ScVectorRefMatrix::SubOp called"); +} + +void ScVectorRefMatrix::MulOp(double fVal, ScMatrix& rMat) +{ + throw std::runtime_error("ScVectorRefMatrix::MulOp called"); +} + +void ScVectorRefMatrix::DivOp(bool bFlag, double fVal, ScMatrix& rMat) +{ + throw std::runtime_error("ScVectorRefMatrix::DivOp called"); +} + +void ScVectorRefMatrix::PowOp(bool bFlag, double fVal, ScMatrix& rMat) +{ + throw std::runtime_error("ScVectorRefMatrix::PowOp called"); +} + +std::vector<ScMatrix::IterateResult> ScVectorRefMatrix::Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) +{ + throw std::runtime_error("ScVectorRefMatrix::Collect called"); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 02226081592e47b0c42489258ed688b9ebb7a939 Author: Jan Holesovsky <ke...@collabora.com> Date: Thu Nov 19 12:42:36 2015 +0100 sc: Introduce Abstract Base Class for ScMatrix, for a future rework. We want to introduce another type of ScMatrix that will directly contain DoubleVectorRefToken and operate on that. The idea is that it is pointless to construct a ScMatrix via lots of copying around, when we already have a nice array of doubles. Change-Id: I3e5d7b9e2e0f9b9bf350336a8582cfd852586b3f diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index 883550d..1f5d438 100644 --- a/sc/inc/scmatrix.hxx +++ b/sc/inc/scmatrix.hxx @@ -106,24 +106,18 @@ struct ScMatrixValue } }; -/** - * Matrix data type that can store values of mixed types. Each element can - * be one of the following types: numeric, string, boolean, empty, and empty - * path. - */ +/// Abstract base class for ScFullMatrix and ScSubMatrix implementations. class SC_DLLPUBLIC ScMatrix { - friend class ScMatrixImpl; - - std::unique_ptr<ScMatrixImpl> pImpl; mutable size_t nRefCnt; // reference count - - // only delete via Delete() - ~ScMatrix(); + bool mbCloneIfConst; // Whether the matrix is cloned with a CloneIfConst() call. ScMatrix( const ScMatrix& ) = delete; ScMatrix& operator=( const ScMatrix&) = delete; +protected: + virtual ~ScMatrix() {} + public: enum Op { Add, Sub, Mul, Div }; @@ -202,13 +196,10 @@ public: return (nType & SC_MATVAL_NONVALUE) == SC_MATVAL_EMPTYPATH; } - ScMatrix(SCSIZE nC, SCSIZE nR); - ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal); - - ScMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals ); + ScMatrix() : nRefCnt(0), mbCloneIfConst(true) {} /** Clone the matrix. */ - ScMatrix* Clone() const; + virtual ScMatrix* Clone() const = 0; /** Clone the matrix if mbCloneIfConst (immutable) is set, otherwise return _this_ matrix, to be assigned to a ScMatrixRef. */ @@ -221,21 +212,21 @@ public: /** * Resize the matrix to specified new dimension. */ - void Resize( SCSIZE nC, SCSIZE nR); + virtual void Resize(SCSIZE nC, SCSIZE nR) = 0; - void Resize(SCSIZE nC, SCSIZE nR, double fVal); + virtual void Resize(SCSIZE nC, SCSIZE nR, double fVal) = 0; /** Clone the matrix and extend it to the new size. nNewCols and nNewRows MUST be at least of the size of the original matrix. */ - ScMatrix* CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const; + virtual ScMatrix* CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const = 0; void IncRef() const; void DecRef() const; - void SetErrorInterpreter( ScInterpreter* p); - void GetDimensions( SCSIZE& rC, SCSIZE& rR) const; - SCSIZE GetElementCount() const; - bool ValidColRow( SCSIZE nC, SCSIZE nR) const; + virtual void SetErrorInterpreter( ScInterpreter* p) = 0; + virtual void GetDimensions( SCSIZE& rC, SCSIZE& rR) const = 0; + virtual SCSIZE GetElementCount() const = 0; + virtual bool ValidColRow( SCSIZE nC, SCSIZE nR) const = 0; /** For a row vector or column vector, if the position does not point into the vector but is a valid column or row offset it is adapted such that @@ -243,7 +234,7 @@ public: vector, same row column 0 for a column vector. Else, for a 2D matrix, returns false. */ - bool ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const; + virtual bool ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const = 0; /** Checks if the matrix position is within the matrix. If it is not, for a row vector or column vector the position is adapted such that it points @@ -251,47 +242,47 @@ public: same row column 0 for a column vector. Else, for a 2D matrix and position not within matrix, returns false. */ - bool ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const; + virtual bool ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const = 0; - void PutDouble( double fVal, SCSIZE nC, SCSIZE nR); - void PutDouble( double fVal, SCSIZE nIndex); - void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR); + virtual void PutDouble( double fVal, SCSIZE nC, SCSIZE nR) = 0; + virtual void PutDouble( double fVal, SCSIZE nIndex) = 0; + virtual void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) = 0; - void PutString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR); - void PutString( const svl::SharedString& rStr, SCSIZE nIndex); - void PutString( const svl::SharedString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR); + virtual void PutString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR) = 0; + virtual void PutString( const svl::SharedString& rStr, SCSIZE nIndex) = 0; + virtual void PutString( const svl::SharedString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) = 0; - void PutEmpty( SCSIZE nC, SCSIZE nR); + virtual void PutEmpty( SCSIZE nC, SCSIZE nR) = 0; /// Jump sal_False without path - void PutEmptyPath( SCSIZE nC, SCSIZE nR); - void PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR ); - void PutBoolean( bool bVal, SCSIZE nC, SCSIZE nR); + virtual void PutEmptyPath( SCSIZE nC, SCSIZE nR) = 0; + virtual void PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR ) = 0; + virtual void PutBoolean( bool bVal, SCSIZE nC, SCSIZE nR) = 0; - void FillDouble( double fVal, - SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 ); + virtual void FillDouble( double fVal, + SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 ) = 0; /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */ - void PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR ); + virtual void PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR ) = 0; /** Put a column vector of strings, starting at row nR, must fit into dimensions. */ - void PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR ); + virtual void PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR ) = 0; /** Put a column vector of empties, starting at row nR, must fit into dimensions. */ - void PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ); + virtual void PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) = 0; /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */ - void PutEmptyResultVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ); + virtual void PutEmptyResultVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) = 0; /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */ - void PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ); + virtual void PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) = 0; /** May be used before obtaining the double value of an element to avoid passing its NAN around. @ATTENTION: MUST NOT be used if the element is a string! Use GetErrorIfNotString() instead if not sure. @returns 0 if no error, else one of err... constants */ - sal_uInt16 GetError( SCSIZE nC, SCSIZE nR) const; + virtual sal_uInt16 GetError( SCSIZE nC, SCSIZE nR) const = 0; /** Use in ScInterpreter to obtain the error code, if any. @returns 0 if no error or string element, else one of err... constants */ @@ -299,85 +290,291 @@ public: { return IsValue( nC, nR) ? GetError( nC, nR) : 0; } /// @return 0.0 if empty or empty path, else value or DoubleError. - double GetDouble( SCSIZE nC, SCSIZE nR) const; + virtual double GetDouble( SCSIZE nC, SCSIZE nR) const = 0; + /// @return 0.0 if empty or empty path, else value or DoubleError. + virtual double GetDouble( SCSIZE nIndex) const = 0; + + /// @return empty string if empty or empty path, else string content. + virtual svl::SharedString GetString( SCSIZE nC, SCSIZE nR) const = 0; + /// @return empty string if empty or empty path, else string content. + virtual svl::SharedString GetString( SCSIZE nIndex) const = 0; + + /** @returns the matrix element's string if one is present, otherwise the + numerical value formatted as string, or in case of an error the error + string is returned; an empty string for empty, a "FALSE" string for + empty path. */ + virtual svl::SharedString GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const = 0; + + /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate + /// an empty string! + virtual ScMatrixValue Get( SCSIZE nC, SCSIZE nR) const = 0; + + /// @return <TRUE/> if string or empty or empty path, in fact non-value. + virtual bool IsString( SCSIZE nIndex ) const = 0; + + /// @return <TRUE/> if string or empty or empty path, in fact non-value. + virtual bool IsString( SCSIZE nC, SCSIZE nR ) const = 0; + + /// @return <TRUE/> if empty or empty cell or empty result, not empty path. + virtual bool IsEmpty( SCSIZE nC, SCSIZE nR ) const = 0; + + /// @return <TRUE/> if empty cell, not empty or empty result or empty path. + virtual bool IsEmptyCell( SCSIZE nC, SCSIZE nR ) const = 0; + + /// @return <TRUE/> if empty result, not empty or empty cell or empty path. + virtual bool IsEmptyResult( SCSIZE nC, SCSIZE nR ) const = 0; + + /// @return <TRUE/> if empty path, not empty or empty cell or empty result. + virtual bool IsEmptyPath( SCSIZE nC, SCSIZE nR ) const = 0; + + /// @return <TRUE/> if value or boolean. + virtual bool IsValue( SCSIZE nIndex ) const = 0; + + /// @return <TRUE/> if value or boolean. + virtual bool IsValue( SCSIZE nC, SCSIZE nR ) const = 0; + + /// @return <TRUE/> if value or boolean or empty or empty path. + virtual bool IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const = 0; + + /// @return <TRUE/> if boolean. + virtual bool IsBoolean( SCSIZE nC, SCSIZE nR ) const = 0; + + /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties + virtual bool IsNumeric() const = 0; + + virtual void MatTrans( ScMatrix& mRes) const = 0; + virtual void MatCopy ( ScMatrix& mRes) const = 0; + + // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values + virtual void CompareEqual() = 0; + virtual void CompareNotEqual() = 0; + virtual void CompareLess() = 0; + virtual void CompareGreater() = 0; + virtual void CompareLessEqual() = 0; + virtual void CompareGreaterEqual() = 0; + + virtual double And() const = 0; // logical AND of all matrix values, or NAN + virtual double Or() const = 0; // logical OR of all matrix values, or NAN + virtual double Xor() const = 0; // logical XOR of all matrix values, or NAN + + virtual IterateResult Sum(bool bTextAsZero) const = 0; + virtual IterateResult SumSquare(bool bTextAsZero) const = 0; + virtual IterateResult Product(bool bTextAsZero) const = 0; + virtual size_t Count(bool bCountStrings) const = 0; + virtual size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const = 0; + virtual size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const = 0; + + virtual double GetMaxValue( bool bTextAsZero ) const = 0; + virtual double GetMinValue( bool bTextAsZero ) const = 0; + + virtual ScMatrixRef CompareMatrix( + sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions = nullptr ) const = 0; + + /** + * Convert the content of matrix into a linear array of numeric values. + * String elements are mapped to NaN's and empty elements are mapped to + * either NaN or zero values. + * + * @param bEmptyAsZero if true empty elements are mapped to zero values, + * otherwise they become NaN values. + */ + virtual void GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero = true ) const = 0; + virtual void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const = 0; + + virtual void NotOp(ScMatrix& rMat) = 0; + virtual void NegOp(ScMatrix& rMat) = 0; + virtual void AddOp(double fVal, ScMatrix& rMat) = 0; + virtual void SubOp(bool bFlag, double fVal, ScMatrix& rMat) = 0; + virtual void MulOp(double fVal, ScMatrix& rMat) = 0; + virtual void DivOp(bool bFlag, double fVal, ScMatrix& rMat) = 0; + virtual void PowOp(bool bFlag, double fVal, ScMatrix& rMat) = 0; + + virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) = 0; + +#if DEBUG_MATRIX + void Dump() const; +#endif +}; + +/** + * Matrix data type that can store values of mixed types. Each element can + * be one of the following types: numeric, string, boolean, empty, and empty + * path. + */ +class SC_DLLPUBLIC ScFullMatrix : public ScMatrix +{ + friend class ScMatrixImpl; + + std::unique_ptr<ScMatrixImpl> pImpl; + + // only delete via Delete() + virtual ~ScFullMatrix(); + + ScFullMatrix( const ScFullMatrix& ) = delete; + ScFullMatrix& operator=( const ScFullMatrix&) = delete; + +public: + + ScFullMatrix(SCSIZE nC, SCSIZE nR); + ScFullMatrix(SCSIZE nC, SCSIZE nR, double fInitVal); + + ScFullMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals ); + + /** Clone the matrix. */ + virtual ScMatrix* Clone() const override; + + /** + * Resize the matrix to specified new dimension. + */ + virtual void Resize( SCSIZE nC, SCSIZE nR) override; + + virtual void Resize(SCSIZE nC, SCSIZE nR, double fVal) override; + + /** Clone the matrix and extend it to the new size. nNewCols and nNewRows + MUST be at least of the size of the original matrix. */ + virtual ScMatrix* CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const override; + + virtual void SetErrorInterpreter( ScInterpreter* p) override; + virtual void GetDimensions( SCSIZE& rC, SCSIZE& rR) const override; + virtual SCSIZE GetElementCount() const override; + virtual bool ValidColRow( SCSIZE nC, SCSIZE nR) const override; + + /** For a row vector or column vector, if the position does not point into + the vector but is a valid column or row offset it is adapted such that + it points to an element to be replicated, same column row 0 for a row + vector, same row column 0 for a column vector. Else, for a 2D matrix, + returns false. + */ + virtual bool ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const override; + + /** Checks if the matrix position is within the matrix. If it is not, for a + row vector or column vector the position is adapted such that it points + to an element to be replicated, same column row 0 for a row vector, + same row column 0 for a column vector. Else, for a 2D matrix and + position not within matrix, returns false. + */ + virtual bool ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const override; + + virtual void PutDouble( double fVal, SCSIZE nC, SCSIZE nR) override; + virtual void PutDouble( double fVal, SCSIZE nIndex) override; + virtual void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) override; + + virtual void PutString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR) override; + virtual void PutString( const svl::SharedString& rStr, SCSIZE nIndex) override; + virtual void PutString( const svl::SharedString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) override; + + virtual void PutEmpty( SCSIZE nC, SCSIZE nR) override; + + /// Jump sal_False without path + virtual void PutEmptyPath( SCSIZE nC, SCSIZE nR) override; + virtual void PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR ) override; + virtual void PutBoolean( bool bVal, SCSIZE nC, SCSIZE nR) override; + + virtual void FillDouble( double fVal, + SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 ) override; + + /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */ + virtual void PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR ) override; + + /** Put a column vector of strings, starting at row nR, must fit into dimensions. */ + virtual void PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR ) override; + + /** Put a column vector of empties, starting at row nR, must fit into dimensions. */ + virtual void PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) override; + + /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */ + virtual void PutEmptyResultVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) override; + + /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */ + virtual void PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) override; + + /** May be used before obtaining the double value of an element to avoid + passing its NAN around. + @ATTENTION: MUST NOT be used if the element is a string! + Use GetErrorIfNotString() instead if not sure. + @returns 0 if no error, else one of err... constants */ + virtual sal_uInt16 GetError( SCSIZE nC, SCSIZE nR) const override; + + /// @return 0.0 if empty or empty path, else value or DoubleError. + virtual double GetDouble( SCSIZE nC, SCSIZE nR) const override; /// @return 0.0 if empty or empty path, else value or DoubleError. - double GetDouble( SCSIZE nIndex) const; + virtual double GetDouble( SCSIZE nIndex) const override; /// @return empty string if empty or empty path, else string content. - svl::SharedString GetString( SCSIZE nC, SCSIZE nR) const; + virtual svl::SharedString GetString( SCSIZE nC, SCSIZE nR) const override; /// @return empty string if empty or empty path, else string content. - svl::SharedString GetString( SCSIZE nIndex) const; + virtual svl::SharedString GetString( SCSIZE nIndex) const override; /** @returns the matrix element's string if one is present, otherwise the numerical value formatted as string, or in case of an error the error string is returned; an empty string for empty, a "FALSE" string for empty path. */ - svl::SharedString GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const; + virtual svl::SharedString GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const override; /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate /// an empty string! - ScMatrixValue Get( SCSIZE nC, SCSIZE nR) const; + virtual ScMatrixValue Get( SCSIZE nC, SCSIZE nR) const override; /// @return <TRUE/> if string or empty or empty path, in fact non-value. - bool IsString( SCSIZE nIndex ) const; + virtual bool IsString( SCSIZE nIndex ) const override; /// @return <TRUE/> if string or empty or empty path, in fact non-value. - bool IsString( SCSIZE nC, SCSIZE nR ) const; + virtual bool IsString( SCSIZE nC, SCSIZE nR ) const override; /// @return <TRUE/> if empty or empty cell or empty result, not empty path. - bool IsEmpty( SCSIZE nC, SCSIZE nR ) const; + virtual bool IsEmpty( SCSIZE nC, SCSIZE nR ) const override; /// @return <TRUE/> if empty cell, not empty or empty result or empty path. - bool IsEmptyCell( SCSIZE nC, SCSIZE nR ) const; + virtual bool IsEmptyCell( SCSIZE nC, SCSIZE nR ) const override; /// @return <TRUE/> if empty result, not empty or empty cell or empty path. - bool IsEmptyResult( SCSIZE nC, SCSIZE nR ) const; + virtual bool IsEmptyResult( SCSIZE nC, SCSIZE nR ) const override; /// @return <TRUE/> if empty path, not empty or empty cell or empty result. - bool IsEmptyPath( SCSIZE nC, SCSIZE nR ) const; + virtual bool IsEmptyPath( SCSIZE nC, SCSIZE nR ) const override; /// @return <TRUE/> if value or boolean. - bool IsValue( SCSIZE nIndex ) const; + virtual bool IsValue( SCSIZE nIndex ) const override; /// @return <TRUE/> if value or boolean. - bool IsValue( SCSIZE nC, SCSIZE nR ) const; + virtual bool IsValue( SCSIZE nC, SCSIZE nR ) const override; /// @return <TRUE/> if value or boolean or empty or empty path. - bool IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const; + virtual bool IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const override; /// @return <TRUE/> if boolean. - bool IsBoolean( SCSIZE nC, SCSIZE nR ) const; + virtual bool IsBoolean( SCSIZE nC, SCSIZE nR ) const override; /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties - bool IsNumeric() const; + virtual bool IsNumeric() const override; - void MatTrans( ScMatrix& mRes) const; - void MatCopy ( ScMatrix& mRes) const; + virtual void MatTrans( ScMatrix& mRes) const override; + virtual void MatCopy ( ScMatrix& mRes) const override; // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values - void CompareEqual(); - void CompareNotEqual(); - void CompareLess(); - void CompareGreater(); - void CompareLessEqual(); - void CompareGreaterEqual(); - - double And() const; // logical AND of all matrix values, or NAN - double Or() const; // logical OR of all matrix values, or NAN - double Xor() const; // logical XOR of all matrix values, or NAN - - IterateResult Sum(bool bTextAsZero) const; - IterateResult SumSquare(bool bTextAsZero) const; - IterateResult Product(bool bTextAsZero) const; - size_t Count(bool bCountStrings) const; - size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const; - size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const; - - double GetMaxValue( bool bTextAsZero ) const; - double GetMinValue( bool bTextAsZero ) const; - - ScMatrixRef CompareMatrix( - sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions = nullptr ) const; + virtual void CompareEqual() override; + virtual void CompareNotEqual() override; + virtual void CompareLess() override; + virtual void CompareGreater() override; + virtual void CompareLessEqual() override; + virtual void CompareGreaterEqual() override; + + virtual double And() const override; // logical AND of all matrix values, or NAN + virtual double Or() const override; // logical OR of all matrix values, or NAN + virtual double Xor() const override; // logical XOR of all matrix values, or NAN + + virtual IterateResult Sum(bool bTextAsZero) const override; + virtual IterateResult SumSquare(bool bTextAsZero) const override; + virtual IterateResult Product(bool bTextAsZero) const override; + virtual size_t Count(bool bCountStrings) const override; + virtual size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const override; + virtual size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const override; + + virtual double GetMaxValue( bool bTextAsZero ) const override; + virtual double GetMinValue( bool bTextAsZero ) const override; + + virtual ScMatrixRef CompareMatrix( + sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions = nullptr ) const override; /** * Convert the content of matrix into a linear array of numeric values. @@ -387,20 +584,20 @@ public: * @param bEmptyAsZero if true empty elements are mapped to zero values, * otherwise they become NaN values. */ - void GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero = true ) const; - void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const; + virtual void GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero = true ) const override; + virtual void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const override; - void NotOp(ScMatrix& rMat); - void NegOp(ScMatrix& rMat); - void AddOp(double fVal, ScMatrix& rMat); - void SubOp(bool bFlag, double fVal, ScMatrix& rMat); - void MulOp(double fVal, ScMatrix& rMat); - void DivOp(bool bFlag, double fVal, ScMatrix& rMat); - void PowOp(bool bFlag, double fVal, ScMatrix& rMat); + virtual void NotOp(ScMatrix& rMat) override; + virtual void NegOp(ScMatrix& rMat) override; + virtual void AddOp(double fVal, ScMatrix& rMat) override; + virtual void SubOp(bool bFlag, double fVal, ScMatrix& rMat) override; + virtual void MulOp(double fVal, ScMatrix& rMat) override; + virtual void DivOp(bool bFlag, double fVal, ScMatrix& rMat) override; + virtual void PowOp(bool bFlag, double fVal, ScMatrix& rMat) override; - std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp); + virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) override; - ScMatrix& operator+= ( const ScMatrix& r ); + ScFullMatrix& operator+= ( const ScFullMatrix& r ); #if DEBUG_MATRIX void Dump() const; diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 3fc85a6..bf22802 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -1889,7 +1889,7 @@ void Test::testMatrix() ScMatrixRef pMat, pMat2; // First, test the zero matrix type. - pMat = new ScMatrix(0, 0, 0.0); + pMat = new ScFullMatrix(0, 0, 0.0); SCSIZE nC, nR; pMat->GetDimensions(nC, nR); CPPUNIT_ASSERT_MESSAGE("matrix is not empty", nC == 0 && nR == 0); @@ -1912,7 +1912,7 @@ void Test::testMatrix() pMat->And() && pMat->Or()); // Test the AND and OR evaluations. - pMat = new ScMatrix(2, 2, 0.0); + pMat = new ScFullMatrix(2, 2, 0.0); // Only some of the elements are non-zero. pMat->PutBoolean(true, 0, 0); @@ -1927,7 +1927,7 @@ void Test::testMatrix() CPPUNIT_ASSERT_MESSAGE("incorrect AND result", pMat->And()); // Now test the emtpy matrix type. - pMat = new ScMatrix(10, 20); + pMat = new ScFullMatrix(10, 20); pMat->GetDimensions(nC, nR); CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 10 && nR == 20); checkMatrixElements<AllEmptyMatrix>(*pMat); @@ -1939,7 +1939,7 @@ void Test::testMatrix() checkMatrixElements<PartiallyFilledEmptyMatrix>(*pMat); // Test resizing. - pMat = new ScMatrix(0, 0); + pMat = new ScFullMatrix(0, 0); pMat->Resize(2, 2, 1.5); pMat->PutEmpty(1, 1); @@ -1949,7 +1949,7 @@ void Test::testMatrix() CPPUNIT_ASSERT_MESSAGE("PutEmpty() call failed.", pMat->IsEmpty(1, 1)); // Max and min values. - pMat = new ScMatrix(2, 2, 0.0); + pMat = new ScFullMatrix(2, 2, 0.0); pMat->PutDouble(-10, 0, 0); pMat->PutDouble(-12, 0, 1); pMat->PutDouble(-8, 1, 0); @@ -1961,7 +1961,7 @@ void Test::testMatrix() CPPUNIT_ASSERT_EQUAL(-8.0, pMat->GetMaxValue(false)); // ignore text. pMat->PutBoolean(true, 0, 0); CPPUNIT_ASSERT_EQUAL(1.0, pMat->GetMaxValue(false)); - pMat = new ScMatrix(2, 2, 10.0); + pMat = new ScFullMatrix(2, 2, 10.0); pMat->PutBoolean(false, 0, 0); pMat->PutDouble(12.5, 1, 1); CPPUNIT_ASSERT_EQUAL(0.0, pMat->GetMinValue(false)); @@ -1969,7 +1969,7 @@ void Test::testMatrix() // Convert matrix into a linear double array. String elements become NaN // and empty elements become 0. - pMat = new ScMatrix(3, 3); + pMat = new ScFullMatrix(3, 3); pMat->PutDouble(2.5, 0, 0); pMat->PutDouble(1.2, 0, 1); pMat->PutString(rPool.intern("A"), 1, 1); @@ -1994,7 +1994,7 @@ void Test::testMatrix() } } - pMat2 = new ScMatrix(3, 3, 10.0); + pMat2 = new ScFullMatrix(3, 3, 10.0); pMat2->PutString(rPool.intern("B"), 1, 0); pMat2->MergeDoubleArray(aDoubles, ScMatrix::Mul); diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index 655954e..df05e22 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -2169,7 +2169,7 @@ formula::FormulaTokenRef ScTable::ResolveStaticReference( SCCOL nCol1, SCROW nRo if (!ValidCol(nCol1) || !ValidCol(nCol2) || !ValidRow(nRow1) || !ValidRow(nRow2)) return formula::FormulaTokenRef(); - ScMatrixRef pMat(new ScMatrix(nCol2-nCol1+1, nRow2-nRow1+1, 0.0)); + ScMatrixRef pMat(new ScFullMatrix(nCol2-nCol1+1, nRow2-nRow1+1, 0.0)); for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) { if (!aCol[nCol].ResolveStaticReference(*pMat, nCol2-nCol1, nRow1, nRow2)) diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx index 37a1bc9..437434a 100644 --- a/sc/source/core/data/validat.cxx +++ b/sc/source/core/data/validat.cxx @@ -643,7 +643,7 @@ bool ScValidationData::GetSelectionFromFormula( // is stored as a single value. // Use an interim matrix to create the TypedStrData below. - xMatRef = new ScMatrix(1, 1, 0.0); + xMatRef = new ScFullMatrix(1, 1, 0.0); sal_uInt16 nErrCode = aValidationSrc.GetErrCode(); if (nErrCode) diff --git a/sc/source/core/tool/addincol.cxx b/sc/source/core/tool/addincol.cxx index 2618a51..ff9aaac 100644 --- a/sc/source/core/tool/addincol.cxx +++ b/sc/source/core/tool/addincol.cxx @@ -1576,7 +1576,7 @@ void ScUnoAddInCall::SetResult( const uno::Any& rNewRes ) } if ( nMaxColCount && nRowCount ) { - xMatrix = new ScMatrix( + xMatrix = new ScFullMatrix( static_cast<SCSIZE>(nMaxColCount), static_cast<SCSIZE>(nRowCount), 0.0); for (long nRow=0; nRow<nRowCount; nRow++) @@ -1617,7 +1617,7 @@ void ScUnoAddInCall::SetResult( const uno::Any& rNewRes ) } if ( nMaxColCount && nRowCount ) { - xMatrix = new ScMatrix( + xMatrix = new ScFullMatrix( static_cast<SCSIZE>(nMaxColCount), static_cast<SCSIZE>(nRowCount), 0.0); for (long nRow=0; nRow<nRowCount; nRow++) @@ -1658,7 +1658,7 @@ void ScUnoAddInCall::SetResult( const uno::Any& rNewRes ) } if ( nMaxColCount && nRowCount ) { - xMatrix = new ScMatrix( + xMatrix = new ScFullMatrix( static_cast<SCSIZE>(nMaxColCount), static_cast<SCSIZE>(nRowCount), 0.0); for (long nRow=0; nRow<nRowCount; nRow++) diff --git a/sc/source/core/tool/ddelink.cxx b/sc/source/core/tool/ddelink.cxx index 22f05e4..8a78554 100644 --- a/sc/source/core/tool/ddelink.cxx +++ b/sc/source/core/tool/ddelink.cxx @@ -89,7 +89,7 @@ ScDdeLink::ScDdeLink( ScDocument* pD, SvStream& rStream, ScMultipleReadHeader& r bool bHasValue; rStream.ReadCharAsBool( bHasValue ); if ( bHasValue ) - pResult = new ScMatrix(0, 0); + pResult = new ScFullMatrix(0, 0); if (rHdr.BytesLeft()) // neu in 388b und der 364w (RealTime-Client) Version rStream.ReadUChar( nMode ); @@ -155,7 +155,7 @@ sfx2::SvBaseLink::UpdateResult ScDdeLink::DataChanged( else // Daten aufteilen { // Matrix immer neu anlegen, damit bIsString nicht durcheinanderkommt - pResult = new ScMatrix(nCols, nRows, 0.0); + pResult = new ScFullMatrix(nCols, nRows, 0.0); SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); svl::SharedStringPool& rPool = pDoc->GetSharedStringPool(); diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx index 085dc0f..a9f8a61 100644 --- a/sc/source/core/tool/formulagroup.cxx +++ b/sc/source/core/tool/formulagroup.cxx @@ -376,7 +376,7 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres if (!p2->IsEndFixed()) nRowEnd += i; size_t nRowSize = nRowEnd - nRowStart + 1; - ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize)); + ScMatrixRef pMat(new ScFullMatrix(nColSize, nRowSize)); size_t nDataRowEnd = p2->GetArrayLength() - 1; if (nRowStart > nDataRowEnd) diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 5517f48..bf3c0e2 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -4651,7 +4651,7 @@ double ScInterpreter::IterateParametersIf( ScIterFuncIf eFunc ) break; case svExternalSingleRef: { - pSumExtraMatrix = new ScMatrix(1, 1, 0.0); + pSumExtraMatrix = new ScFullMatrix(1, 1, 0.0); ScExternalRefCache::TokenRef pToken; PopExternalSingleRef(pToken); if (!pToken) @@ -5903,7 +5903,7 @@ void ScInterpreter::ScLookup() ScMatrixRef pDataMat2; if (bVertical) { - ScMatrixRef pTempMat(new ScMatrix(1, nR, 0.0)); + ScMatrixRef pTempMat(new ScFullMatrix(1, nR, 0.0)); for (SCSIZE i = 0; i < nR; ++i) if (pDataMat->IsValue(0, i)) pTempMat->PutDouble(pDataMat->GetDouble(0, i), 0, i); @@ -5913,7 +5913,7 @@ void ScInterpreter::ScLookup() } else { - ScMatrixRef pTempMat(new ScMatrix(nC, 1, 0.0)); + ScMatrixRef pTempMat(new ScFullMatrix(nC, 1, 0.0)); for (SCSIZE i = 0; i < nC; ++i) if (pDataMat->IsValue(i, 0)) pTempMat->PutDouble(pDataMat->GetDouble(i, 0), i, 0); diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx index eb9852e..a0933c0 100644 --- a/sc/source/core/tool/interpr5.cxx +++ b/sc/source/core/tool/interpr5.cxx @@ -319,9 +319,9 @@ ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty) { ScMatrixRef pMat; if (bEmpty) - pMat = new ScMatrix(nC, nR); + pMat = new ScFullMatrix(nC, nR); else - pMat = new ScMatrix(nC, nR, 0.0); + pMat = new ScFullMatrix(nC, nR, 0.0); pMat->SetErrorInterpreter( this); // A temporary matrix is mutable and ScMatrix::CloneIfConst() returns the @@ -463,17 +463,17 @@ ScMatrixRef ScInterpreter::GetMatrix() } if (pToken->GetType() == svDouble) { - pMat = new ScMatrix(1, 1, 0.0); + pMat = new ScFullMatrix(1, 1, 0.0); pMat->PutDouble(pToken->GetDouble(), 0, 0); } else if (pToken->GetType() == svString) { - pMat = new ScMatrix(1, 1, 0.0); + pMat = new ScFullMatrix(1, 1, 0.0); pMat->PutString(pToken->GetString(), 0, 0); } else { - pMat = new ScMatrix(1, 1); + pMat = new ScFullMatrix(1, 1); } } break; diff --git a/sc/source/core/tool/jumpmatrix.cxx b/sc/source/core/tool/jumpmatrix.cxx index ea27b97..f02612c2 100644 --- a/sc/source/core/tool/jumpmatrix.cxx +++ b/sc/source/core/tool/jumpmatrix.cxx @@ -29,7 +29,7 @@ const SCSIZE kBufferThreshhold = 128; ScJumpMatrix::ScJumpMatrix(SCSIZE nColsP, SCSIZE nRowsP) : pJump(new ScJumpMatrixEntry[nColsP * nRowsP]) - , pMat(new ScMatrix(nColsP, nRowsP)) + , pMat(new ScFullMatrix(nColsP, nRowsP)) , pParams(nullptr) , nCols(nColsP) , nRows(nRowsP) diff --git a/sc/source/core/tool/rangeseq.cxx b/sc/source/core/tool/rangeseq.cxx index 6ec7e71..20b9419 100644 --- a/sc/source/core/tool/rangeseq.cxx +++ b/sc/source/core/tool/rangeseq.cxx @@ -372,7 +372,7 @@ ScMatrixRef ScSequenceToMatrix::CreateMixedMatrix( const css::uno::Any & rAny ) if ( nMaxColCount && nRowCount ) { OUString aUStr; - xMatrix = new ScMatrix( + xMatrix = new ScFullMatrix( static_cast<SCSIZE>(nMaxColCount), static_cast<SCSIZE>(nRowCount), 0.0); SCSIZE nCols, nRows; diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index 2af2df3..e3823bd 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -208,7 +208,6 @@ class ScMatrixImpl: private boost::noncopyable MatrixImplType maMat; MatrixImplType maMatFlag; ScInterpreter* pErrorInterpreter; - bool mbCloneIfConst; // Whether the matrix is cloned with a CloneIfConst() call. public: ScMatrixImpl(SCSIZE nC, SCSIZE nR); @@ -219,8 +218,6 @@ public: ~ScMatrixImpl(); void Clear(); - void SetImmutable(bool bVal); - bool IsImmutable() const { return mbCloneIfConst;} void Resize(SCSIZE nC, SCSIZE nR); void Resize(SCSIZE nC, SCSIZE nR, double fVal); void SetErrorInterpreter( ScInterpreter* p); @@ -282,9 +279,9 @@ public: double Or() const; double Xor() const; - ScMatrix::IterateResult Sum(bool bTextAsZero) const; - ScMatrix::IterateResult SumSquare(bool bTextAsZero) const; - ScMatrix::IterateResult Product(bool bTextAsZero) const; + ScFullMatrix::IterateResult Sum(bool bTextAsZero) const; + ScFullMatrix::IterateResult SumSquare(bool bTextAsZero) const; + ScFullMatrix::IterateResult Product(bool bTextAsZero) const; size_t Count(bool bCountStrings) const; size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const; size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const; @@ -295,14 +292,14 @@ public: ScMatrixRef CompareMatrix( sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const; void GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero ) const; - void MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op eOp ) const; + void MergeDoubleArray( std::vector<double>& rArray, ScFullMatrix::Op eOp ) const; void AddValues( const ScMatrixImpl& rMat ); template<typename T> void ApplyOperation(T aOp, ScMatrixImpl& rMat); template<typename T> - std::vector<ScMatrix::IterateResult> ApplyCollectOperation(bool bTextAsZero, const std::vector<std::unique_ptr<T>>& aOp); + std::vector<ScFullMatrix::IterateResult> ApplyCollectOperation(bool bTextAsZero, const std::vector<std::unique_ptr<T>>& aOp); #if DEBUG_MATRIX void Dump() const; @@ -313,13 +310,13 @@ private: }; ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR) : - maMat(nR, nC), maMatFlag(nR, nC, SC_MATFLAG_EMPTYCELL), pErrorInterpreter(nullptr), mbCloneIfConst(true) {} + maMat(nR, nC), maMatFlag(nR, nC, SC_MATFLAG_EMPTYCELL), pErrorInterpreter(nullptr) {} ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal) : - maMat(nR, nC, fInitVal), maMatFlag(nR, nC), pErrorInterpreter(nullptr), mbCloneIfConst(true) {} + maMat(nR, nC, fInitVal), maMatFlag(nR, nC), pErrorInterpreter(nullptr) {} ScMatrixImpl::ScMatrixImpl( size_t nC, size_t nR, const std::vector<double>& rInitVals ) : - maMat(nR, nC, rInitVals.begin(), rInitVals.end()), maMatFlag(nR, nC), pErrorInterpreter(nullptr), mbCloneIfConst(true) {} + maMat(nR, nC, rInitVals.begin(), rInitVals.end()), maMatFlag(nR, nC), pErrorInterpreter(nullptr) {} ScMatrixImpl::~ScMatrixImpl() { @@ -332,11 +329,6 @@ void ScMatrixImpl::Clear() maMatFlag.clear(); } -void ScMatrixImpl::SetImmutable(bool bVal) -{ - mbCloneIfConst = bVal; -} - void ScMatrixImpl::Resize(SCSIZE nC, SCSIZE nR) { maMat.resize(nR, nC); @@ -1007,13 +999,13 @@ template<typename _Op> class WalkElementBlocks { _Op maOp; - ScMatrix::IterateResult maRes; + ScFullMatrix::IterateResult maRes; bool mbFirst:1; bool mbTextAsZero:1; public: WalkElementBlocks(bool bTextAsZero) : maRes(_Op::InitVal, _Op::InitVal, 0), mbFirst(true), mbTextAsZero(bTextAsZero) {} - const ScMatrix::IterateResult& getResult() const { return maRes; } + const ScFullMatrix::IterateResult& getResult() const { return maRes; } void operator() (const MatrixImplType::element_block_node_type& node) { @@ -1076,7 +1068,7 @@ template<typename _Op> class WalkElementBlocksMultipleValues { const std::vector<std::unique_ptr<_Op>>& maOp; - std::vector<ScMatrix::IterateResult> maRes; + std::vector<ScFullMatrix::IterateResult> maRes; bool mbFirst:1; bool mbTextAsZero:1; public: @@ -1090,7 +1082,7 @@ public: maRes.emplace_back(0.0, 0.0, 0); // count } - const std::vector<ScMatrix::IterateResult>& getResult() const { return maRes; } + const std::vector<ScFullMatrix::IterateResult>& getResult() const { return maRes; } void operator() (const MatrixImplType::element_block_node_type& node) { @@ -1760,7 +1752,7 @@ public: namespace { template<typename TOp> -ScMatrix::IterateResult GetValueWithCount(bool bTextAsZero, const MatrixImplType& maMat) +ScFullMatrix::IterateResult GetValueWithCount(bool bTextAsZero, const MatrixImplType& maMat) { WalkElementBlocks<TOp> aFunc(bTextAsZero); maMat.walk(aFunc); @@ -1769,17 +1761,17 @@ ScMatrix::IterateResult GetValueWithCount(bool bTextAsZero, const MatrixImplType } -ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const +ScFullMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const { return GetValueWithCount<sc::op::Sum>(bTextAsZero, maMat); } -ScMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const +ScFullMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const { return GetValueWithCount<sc::op::SumSquare>(bTextAsZero, maMat); } -ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const +ScFullMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const { return GetValueWithCount<sc::op::Product>(bTextAsZero, maMat); } @@ -1839,7 +1831,7 @@ ScMatrixRef ScMatrixImpl::CompareMatrix( if (nSize != rResVal.size()) ScMatrixRef(); - return ScMatrixRef(new ScMatrix(aSize.column, aSize.row, rResVal)); + return ScMatrixRef(new ScFullMatrix(aSize.column, aSize.row, rResVal)); } } @@ -1851,7 +1843,7 @@ ScMatrixRef ScMatrixImpl::CompareMatrix( if (nSize != rResVal.size()) ScMatrixRef(); - return ScMatrixRef(new ScMatrix(aSize.column, aSize.row, rResVal)); + return ScMatrixRef(new ScFullMatrix(aSize.column, aSize.row, rResVal)); } void ScMatrixImpl::GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero ) const @@ -1862,7 +1854,7 @@ void ScMatrixImpl::GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZer aFunc.swap(rArray); } -void ScMatrixImpl::MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op eOp ) const +void ScMatrixImpl::MergeDoubleArray( std::vector<double>& rArray, ScFullMatrix::Op eOp ) const { MatrixImplType::size_pair_type aSize = maMat.size(); size_t nSize = aSize.row*aSize.column; @@ -1871,7 +1863,7 @@ void ScMatrixImpl::MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op e switch (eOp) { - case ScMatrix::Mul: + case ScFullMatrix::Mul: { MergeDoubleArrayFunc<ArrayMul> aFunc(rArray); maMat.walk(aFunc); @@ -2168,7 +2160,7 @@ void ScMatrixImpl::ApplyOperation(T aOp, ScMatrixImpl& rMat) } template<typename T> -std::vector<ScMatrix::IterateResult> ScMatrixImpl::ApplyCollectOperation(bool bTextAsZero, const std::vector<std::unique_ptr<T>>& aOp) +std::vector<ScFullMatrix::IterateResult> ScMatrixImpl::ApplyCollectOperation(bool bTextAsZero, const std::vector<std::unique_ptr<T>>& aOp) { WalkElementBlocksMultipleValues<T> aFunc(bTextAsZero, aOp); maMat.walk(aFunc); @@ -2231,36 +2223,39 @@ void ScMatrix::DecRef() const delete this; } -ScMatrix::ScMatrix( SCSIZE nC, SCSIZE nR) : - pImpl(new ScMatrixImpl(nC, nR)), nRefCnt(0) +ScFullMatrix::ScFullMatrix( SCSIZE nC, SCSIZE nR) : + ScMatrix(), + pImpl(new ScMatrixImpl(nC, nR)) { SAL_WARN_IF( !nC, "sc", "ScMatrix with 0 columns!"); SAL_WARN_IF( !nR, "sc", "ScMatrix with 0 rows!"); } -ScMatrix::ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal) : - pImpl(new ScMatrixImpl(nC, nR, fInitVal)), nRefCnt(0) +ScFullMatrix::ScFullMatrix(SCSIZE nC, SCSIZE nR, double fInitVal) : + ScMatrix(), + pImpl(new ScMatrixImpl(nC, nR, fInitVal)) { SAL_WARN_IF( !nC, "sc", "ScMatrix with 0 columns!"); SAL_WARN_IF( !nR, "sc", "ScMatrix with 0 rows!"); } -ScMatrix::ScMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals ) : - pImpl(new ScMatrixImpl(nC, nR, rInitVals)), nRefCnt(0) +ScFullMatrix::ScFullMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals ) : + ScMatrix(), + pImpl(new ScMatrixImpl(nC, nR, rInitVals)) { SAL_WARN_IF( !nC, "sc", "ScMatrix with 0 columns!"); SAL_WARN_IF( !nR, "sc", "ScMatrix with 0 rows!"); } -ScMatrix::~ScMatrix() +ScFullMatrix::~ScFullMatrix() { } -ScMatrix* ScMatrix::Clone() const +ScMatrix* ScFullMatrix::Clone() const { SCSIZE nC, nR; pImpl->GetDimensions(nC, nR); - ScMatrix* pScMat = new ScMatrix(nC, nR); + ScMatrix* pScMat = new ScFullMatrix(nC, nR); MatCopy(*pScMat); pScMat->SetErrorInterpreter(pImpl->GetErrorInterpreter()); // TODO: really? return pScMat; @@ -2268,339 +2263,345 @@ ScMatrix* ScMatrix::Clone() const ScMatrix* ScMatrix::CloneIfConst() { - return pImpl->IsImmutable() ? Clone() : this; + return mbCloneIfConst ? Clone() : this; } void ScMatrix::SetImmutable( bool bVal ) { - pImpl->SetImmutable(bVal); + mbCloneIfConst = bVal; } -void ScMatrix::Resize( SCSIZE nC, SCSIZE nR) +void ScFullMatrix::Resize( SCSIZE nC, SCSIZE nR) { pImpl->Resize(nC, nR); } -void ScMatrix::Resize(SCSIZE nC, SCSIZE nR, double fVal) +void ScFullMatrix::Resize(SCSIZE nC, SCSIZE nR, double fVal) { pImpl->Resize(nC, nR, fVal); } -ScMatrix* ScMatrix::CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const +ScMatrix* ScFullMatrix::CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const { - ScMatrix* pScMat = new ScMatrix(nNewCols, nNewRows); + ScMatrix* pScMat = new ScFullMatrix(nNewCols, nNewRows); MatCopy(*pScMat); pScMat->SetErrorInterpreter(pImpl->GetErrorInterpreter()); return pScMat; } -void ScMatrix::SetErrorInterpreter( ScInterpreter* p) +void ScFullMatrix::SetErrorInterpreter( ScInterpreter* p) { pImpl->SetErrorInterpreter(p); } -void ScMatrix::GetDimensions( SCSIZE& rC, SCSIZE& rR) const +void ScFullMatrix::GetDimensions( SCSIZE& rC, SCSIZE& rR) const { pImpl->GetDimensions(rC, rR); } -SCSIZE ScMatrix::GetElementCount() const +SCSIZE ScFullMatrix::GetElementCount() const { return pImpl->GetElementCount(); } -bool ScMatrix::ValidColRow( SCSIZE nC, SCSIZE nR) const +bool ScFullMatrix::ValidColRow( SCSIZE nC, SCSIZE nR) const { return pImpl->ValidColRow(nC, nR); } -bool ScMatrix::ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const +bool ScFullMatrix::ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const { return pImpl->ValidColRowReplicated(rC, rR); } -bool ScMatrix::ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const +bool ScFullMatrix::ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const { return ValidColRow( rC, rR) || ValidColRowReplicated( rC, rR); } -void ScMatrix::PutDouble(double fVal, SCSIZE nC, SCSIZE nR) +void ScFullMatrix::PutDouble(double fVal, SCSIZE nC, SCSIZE nR) { pImpl->PutDouble(fVal, nC, nR); } -void ScMatrix::PutDouble( double fVal, SCSIZE nIndex) +void ScFullMatrix::PutDouble( double fVal, SCSIZE nIndex) { pImpl->PutDouble(fVal, nIndex); } -void ScMatrix::PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) +void ScFullMatrix::PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) { pImpl->PutDouble(pArray, nLen, nC, nR); } -void ScMatrix::PutString(const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR) +void ScFullMatrix::PutString(const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR) { pImpl->PutString(rStr, nC, nR); } -void ScMatrix::PutString(const svl::SharedString& rStr, SCSIZE nIndex) +void ScFullMatrix::PutString(const svl::SharedString& rStr, SCSIZE nIndex) { pImpl->PutString(rStr, nIndex); } -void ScMatrix::PutString(const svl::SharedString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) +void ScFullMatrix::PutString(const svl::SharedString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) { pImpl->PutString(pArray, nLen, nC, nR); } -void ScMatrix::PutEmpty(SCSIZE nC, SCSIZE nR) +void ScFullMatrix::PutEmpty(SCSIZE nC, SCSIZE nR) { pImpl->PutEmpty(nC, nR); } -void ScMatrix::PutEmptyPath(SCSIZE nC, SCSIZE nR) +void ScFullMatrix::PutEmptyPath(SCSIZE nC, SCSIZE nR) { pImpl->PutEmptyPath(nC, nR); } -void ScMatrix::PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR ) +void ScFullMatrix::PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR ) { pImpl->PutError(nErrorCode, nC, nR); } -void ScMatrix::PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR) +void ScFullMatrix::PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR) { pImpl->PutBoolean(bVal, nC, nR); } -sal_uInt16 ScMatrix::GetError( SCSIZE nC, SCSIZE nR) const +sal_uInt16 ScFullMatrix::GetError( SCSIZE nC, SCSIZE nR) const { return pImpl->GetError(nC, nR); } -double ScMatrix::GetDouble(SCSIZE nC, SCSIZE nR) const +double ScFullMatrix::GetDouble(SCSIZE nC, SCSIZE nR) const { return pImpl->GetDouble(nC, nR); } -double ScMatrix::GetDouble( SCSIZE nIndex) const +double ScFullMatrix::GetDouble( SCSIZE nIndex) const { return pImpl->GetDouble(nIndex); } -svl::SharedString ScMatrix::GetString(SCSIZE nC, SCSIZE nR) const +svl::SharedString ScFullMatrix::GetString(SCSIZE nC, SCSIZE nR) const { return pImpl->GetString(nC, nR); } -svl::SharedString ScMatrix::GetString( SCSIZE nIndex) const +svl::SharedString ScFullMatrix::GetString( SCSIZE nIndex) const { return pImpl->GetString(nIndex); } -svl::SharedString ScMatrix::GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const +svl::SharedString ScFullMatrix::GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const { return pImpl->GetString(rFormatter, nC, nR); } -ScMatrixValue ScMatrix::Get(SCSIZE nC, SCSIZE nR) const +ScMatrixValue ScFullMatrix::Get(SCSIZE nC, SCSIZE nR) const { return pImpl->Get(nC, nR); } -bool ScMatrix::IsString( SCSIZE nIndex ) const +bool ScFullMatrix::IsString( SCSIZE nIndex ) const { return pImpl->IsString(nIndex); } -bool ScMatrix::IsString( SCSIZE nC, SCSIZE nR ) const +bool ScFullMatrix::IsString( SCSIZE nC, SCSIZE nR ) const { return pImpl->IsString(nC, nR); } -bool ScMatrix::IsEmpty( SCSIZE nC, SCSIZE nR ) const +bool ScFullMatrix::IsEmpty( SCSIZE nC, SCSIZE nR ) const { return pImpl->IsEmpty(nC, nR); } -bool ScMatrix::IsEmptyCell( SCSIZE nC, SCSIZE nR ) const +bool ScFullMatrix::IsEmptyCell( SCSIZE nC, SCSIZE nR ) const { return pImpl->IsEmptyCell(nC, nR); } -bool ScMatrix::IsEmptyResult( SCSIZE nC, SCSIZE nR ) const +bool ScFullMatrix::IsEmptyResult( SCSIZE nC, SCSIZE nR ) const { return pImpl->IsEmptyResult(nC, nR); } -bool ScMatrix::IsEmptyPath( SCSIZE nC, SCSIZE nR ) const +bool ScFullMatrix::IsEmptyPath( SCSIZE nC, SCSIZE nR ) const { return pImpl->IsEmptyPath(nC, nR); } -bool ScMatrix::IsValue( SCSIZE nIndex ) const +bool ScFullMatrix::IsValue( SCSIZE nIndex ) const { return pImpl->IsValue(nIndex); } -bool ScMatrix::IsValue( SCSIZE nC, SCSIZE nR ) const +bool ScFullMatrix::IsValue( SCSIZE nC, SCSIZE nR ) const { return pImpl->IsValue(nC, nR); } -bool ScMatrix::IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const +bool ScFullMatrix::IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const { return pImpl->IsValueOrEmpty(nC, nR); } -bool ScMatrix::IsBoolean( SCSIZE nC, SCSIZE nR ) const +bool ScFullMatrix::IsBoolean( SCSIZE nC, SCSIZE nR ) const { return pImpl->IsBoolean(nC, nR); } -bool ScMatrix::IsNumeric() const +bool ScFullMatrix::IsNumeric() const { return pImpl->IsNumeric(); } -void ScMatrix::MatCopy(ScMatrix& mRes) const +void ScFullMatrix::MatCopy(ScMatrix& mRes) const { - pImpl->MatCopy(*mRes.pImpl); + // FIXME + ScFullMatrix* pMatrix = dynamic_cast<ScFullMatrix*>(&mRes); + assert(pMatrix); + pImpl->MatCopy(*pMatrix->pImpl); } -void ScMatrix::MatTrans(ScMatrix& mRes) const +void ScFullMatrix::MatTrans(ScMatrix& mRes) const { - pImpl->MatTrans(*mRes.pImpl); + // FIXME + ScFullMatrix* pMatrix = dynamic_cast<ScFullMatrix*>(&mRes); + assert(pMatrix); + pImpl->MatTrans(*pMatrix->pImpl); } -void ScMatrix::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 ) +void ScFullMatrix::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 ) { pImpl->FillDouble(fVal, nC1, nR1, nC2, nR2); } -void ScMatrix::PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR ) +void ScFullMatrix::PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR ) { pImpl->PutDoubleVector(rVec, nC, nR); } -void ScMatrix::PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR ) +void ScFullMatrix::PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR ) { pImpl->PutStringVector(rVec, nC, nR); } -void ScMatrix::PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) +void ScFullMatrix::PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) { pImpl->PutEmptyVector(nCount, nC, nR); } -void ScMatrix::PutEmptyResultVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) +void ScFullMatrix::PutEmptyResultVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) { pImpl->PutEmptyResultVector(nCount, nC, nR); } -void ScMatrix::PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) +void ScFullMatrix::PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) { pImpl->PutEmptyPathVector(nCount, nC, nR); } -void ScMatrix::CompareEqual() +void ScFullMatrix::CompareEqual() { pImpl->CompareEqual(); } -void ScMatrix::CompareNotEqual() +void ScFullMatrix::CompareNotEqual() { pImpl->CompareNotEqual(); } -void ScMatrix::CompareLess() +void ScFullMatrix::CompareLess() { pImpl->CompareLess(); } -void ScMatrix::CompareGreater() +void ScFullMatrix::CompareGreater() { pImpl->CompareGreater(); } -void ScMatrix::CompareLessEqual() +void ScFullMatrix::CompareLessEqual() { pImpl->CompareLessEqual(); } -void ScMatrix::CompareGreaterEqual() +void ScFullMatrix::CompareGreaterEqual() { pImpl->CompareGreaterEqual(); } -double ScMatrix::And() const +double ScFullMatrix::And() const { return pImpl->And(); } -double ScMatrix::Or() const +double ScFullMatrix::Or() const { return pImpl->Or(); } -double ScMatrix::Xor() const +double ScFullMatrix::Xor() const { return pImpl->Xor(); } -ScMatrix::IterateResult ScMatrix::Sum(bool bTextAsZero) const +ScFullMatrix::IterateResult ScFullMatrix::Sum(bool bTextAsZero) const { return pImpl->Sum(bTextAsZero); } -ScMatrix::IterateResult ScMatrix::SumSquare(bool bTextAsZero) const +ScFullMatrix::IterateResult ScFullMatrix::SumSquare(bool bTextAsZero) const { return pImpl->SumSquare(bTextAsZero); } -ScMatrix::IterateResult ScMatrix::Product(bool bTextAsZero) const +ScFullMatrix::IterateResult ScFullMatrix::Product(bool bTextAsZero) const { return pImpl->Product(bTextAsZero); } -size_t ScMatrix::Count(bool bCountStrings) const +size_t ScFullMatrix::Count(bool bCountStrings) const { return pImpl->Count(bCountStrings); } -size_t ScMatrix::MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const +size_t ScFullMatrix::MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const { return pImpl->MatchDoubleInColumns(fValue, nCol1, nCol2); } -size_t ScMatrix::MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const +size_t ScFullMatrix::MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const { return pImpl->MatchStringInColumns(rStr, nCol1, nCol2); } -double ScMatrix::GetMaxValue( bool bTextAsZero ) const +double ScFullMatrix::GetMaxValue( bool bTextAsZero ) const { return pImpl->GetMaxValue(bTextAsZero); } -double ScMatrix::GetMinValue( bool bTextAsZero ) const +double ScFullMatrix::GetMinValue( bool bTextAsZero ) const { return pImpl->GetMinValue(bTextAsZero); } -ScMatrixRef ScMatrix::CompareMatrix( +ScMatrixRef ScFullMatrix::CompareMatrix( sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const { return pImpl->CompareMatrix(rComp, nMatPos, pOptions); } -void ScMatrix::GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero ) const +void ScFullMatrix::GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero ) const { pImpl->GetDoubleArray(rArray, bEmptyAsZero); } -void ScMatrix::MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const +void ScFullMatrix::MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const { pImpl->MergeDoubleArray(rArray, eOp); } @@ -2708,95 +2709,125 @@ public: } -void ScMatrix::NotOp( ScMatrix& rMat) +void ScFullMatrix::NotOp( ScMatrix& rMat) { auto not_ = [](double a, double){return double(a == 0.0);}; matop::MatOp<decltype(not_), double> aOp(not_, pImpl->GetErrorInterpreter()); - pImpl->ApplyOperation(aOp, *rMat.pImpl); + // FIXME + ScFullMatrix* pMatrix = dynamic_cast<ScFullMatrix*>(&rMat); + assert(pMatrix); + pImpl->ApplyOperation(aOp, *pMatrix->pImpl); } -void ScMatrix::NegOp( ScMatrix& rMat) +void ScFullMatrix::NegOp( ScMatrix& rMat) { auto neg_ = [](double a, double){return -a;}; matop::MatOp<decltype(neg_), double> aOp(neg_, pImpl->GetErrorInterpreter()); - pImpl->ApplyOperation(aOp, *rMat.pImpl); + // FIXME + ScFullMatrix* pMatrix = dynamic_cast<ScFullMatrix*>(&rMat); + assert(pMatrix); + pImpl->ApplyOperation(aOp, *pMatrix->pImpl); } -void ScMatrix::AddOp( double fVal, ScMatrix& rMat) +void ScFullMatrix::AddOp( double fVal, ScMatrix& rMat) { auto add_ = [](double a, double b){return a + b;}; matop::MatOp<decltype(add_)> aOp(add_, pImpl->GetErrorInterpreter(), fVal); - pImpl->ApplyOperation(aOp, *rMat.pImpl); + // FIXME + ScFullMatrix* pMatrix = dynamic_cast<ScFullMatrix*>(&rMat); + assert(pMatrix); + pImpl->ApplyOperation(aOp, *pMatrix->pImpl); } -void ScMatrix::SubOp( bool bFlag, double fVal, ScMatrix& rMat) +void ScFullMatrix::SubOp( bool bFlag, double fVal, ScMatrix& rMat) { if (bFlag) { auto sub_ = [](double a, double b){return b - a;}; matop::MatOp<decltype(sub_)> aOp(sub_, pImpl->GetErrorInterpreter(), fVal); - pImpl->ApplyOperation(aOp, *rMat.pImpl); + // FIXME + ScFullMatrix* pMatrix = dynamic_cast<ScFullMatrix*>(&rMat); + assert(pMatrix); + pImpl->ApplyOperation(aOp, *pMatrix->pImpl); } else { auto sub_ = [](double a, double b){return a - b;}; matop::MatOp<decltype(sub_)> aOp(sub_, pImpl->GetErrorInterpreter(), fVal); - pImpl->ApplyOperation(aOp, *rMat.pImpl); + // FIXME + ScFullMatrix* pMatrix = dynamic_cast<ScFullMatrix*>(&rMat); + assert(pMatrix); + pImpl->ApplyOperation(aOp, *pMatrix->pImpl); } } -void ScMatrix::MulOp( double fVal, ScMatrix& rMat) +void ScFullMatrix::MulOp( double fVal, ScMatrix& rMat) { auto mul_ = [](double a, double b){return a * b;}; matop::MatOp<decltype(mul_)> aOp(mul_, pImpl->GetErrorInterpreter(), fVal); - pImpl->ApplyOperation(aOp, *rMat.pImpl); + // FIXME + ScFullMatrix* pMatrix = dynamic_cast<ScFullMatrix*>(&rMat); + assert(pMatrix); + pImpl->ApplyOperation(aOp, *pMatrix->pImpl); } -void ScMatrix::DivOp( bool bFlag, double fVal, ScMatrix& rMat) +void ScFullMatrix::DivOp( bool bFlag, double fVal, ScMatrix& rMat) { if (bFlag) { auto div_ = [](double a, double b){return sc::div(b, a);}; ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits