From 8e148863d9683b8b73b28818d144330a607fb511 Mon Sep 17 00:00:00 2001 From: Jan Holesovsky Date: Tue, 24 Nov 2015 10:27:03 +0100 Subject: 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 --- sc/inc/scmatrix.hxx | 200 +++++++++++++- sc/source/core/inc/arraysumfunctor.hxx | 1 + sc/source/core/tool/formulagroup.cxx | 80 +++--- sc/source/core/tool/scmatrix.cxx | 468 +++++++++++++++++++++++++++++++-- 4 files changed, 696 insertions(+), 53 deletions(-) diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index 1f5d4383100d..7f1392b8cf66 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 if string or empty or empty path, in fact non-value. + virtual bool IsString(SCSIZE nIndex) const override; + + /// @return if string or empty or empty path, in fact non-value. + virtual bool IsString(SCSIZE nC, SCSIZE nR) const override; + + /// @return if empty or empty cell or empty result, not empty path. + virtual bool IsEmpty(SCSIZE nC, SCSIZE nR) const override; + + /// @return if empty cell, not empty or empty result or empty path. + virtual bool IsEmptyCell(SCSIZE nC, SCSIZE nR) const override; + + /// @return if empty result, not empty or empty cell or empty path. + virtual bool IsEmptyResult(SCSIZE nC, SCSIZE nR) const override; + + /// @return if empty path, not empty or empty cell or empty result. + virtual bool IsEmptyPath(SCSIZE nC, SCSIZE nR) const override; + + /// @return if value or boolean. + virtual bool IsValue(SCSIZE nIndex) const override; + + /// @return if value or boolean. + virtual bool IsValue(SCSIZE nC, SCSIZE nR) const override; + + /// @return if value or boolean or empty or empty path. + virtual bool IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const override; + + /// @return if boolean. + virtual bool IsBoolean(SCSIZE nC, SCSIZE nR) const override; + + /// @return 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& rVector, bool bEmptyAsZero = true) const override; + virtual void MergeDoubleArray(std::vector& 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 Collect(bool bTextAsZero, const std::vector>& 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 e9ef4041cde6..200fdc6b16f0 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 #include #if defined(LO_SSE2_AVAILABLE) diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx index a9f8a61d6922..c4abe00f402f 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(p); - const std::vector& 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& 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 e3823bdd915e..cb242cadb5b9 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 #include "scmatrix.hxx" #include "global.hxx" #include "address.hxx" #include +#include #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 - std::vector ApplyCollectOperation(bool bTextAsZero, const std::vector>& aOp); + std::vector ApplyCollectOperation(bool bTextAsZero, const std::vector>& aOp); #if DEBUG_MATRIX void Dump() const; @@ -999,13 +1001,13 @@ template 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 class WalkElementBlocksMultipleValues { const std::vector>& maOp; - std::vector maRes; + std::vector 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& getResult() const { return maRes; } + const std::vector& getResult() const { return maRes; } void operator() (const MatrixImplType::element_block_node_type& node) { @@ -1752,7 +1754,7 @@ public: namespace { template -ScFullMatrix::IterateResult GetValueWithCount(bool bTextAsZero, const MatrixImplType& maMat) +ScMatrix::IterateResult GetValueWithCount(bool bTextAsZero, const MatrixImplType& maMat) { WalkElementBlocks 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(bTextAsZero, maMat); } -ScFullMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const +ScMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const { return GetValueWithCount(bTextAsZero, maMat); } -ScFullMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const +ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const { return GetValueWithCount(bTextAsZero, maMat); } @@ -2160,7 +2162,7 @@ void ScMatrixImpl::ApplyOperation(T aOp, ScMatrixImpl& rMat) } template -std::vector ScMatrixImpl::ApplyCollectOperation(bool bTextAsZero, const std::vector>& aOp) +std::vector ScMatrixImpl::ApplyCollectOperation(bool bTextAsZero, const std::vector>& aOp) { WalkElementBlocksMultipleValues 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::Collect(bool bTextAsZero, const std::vector>& aOp) +std::vector ScFullMatrix::Collect(bool bTextAsZero, const std::vector>& 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& 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& rVector, bool bEmptyAsZero) const +{ + throw std::runtime_error("ScVectorRefMatrix::GetDoubleArray called"); +} + +void ScVectorRefMatrix::MergeDoubleArray(std::vector& 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 ScVectorRefMatrix::Collect(bool bTextAsZero, const std::vector>& aOp) +{ + throw std::runtime_error("ScVectorRefMatrix::Collect called"); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3