[Libreoffice-commits] core.git: sc/inc sc/source

Eike Rathke erack at redhat.com
Wed Jan 8 08:29:04 PST 2014


 sc/inc/scmatrix.hxx                |   12 +++
 sc/source/core/inc/jumpmatrix.hxx  |   31 +++++++++
 sc/source/core/tool/interpr1.cxx   |   71 ++++++++++------------
 sc/source/core/tool/jumpmatrix.cxx |  119 +++++++++++++++++++++++++++++++++++--
 sc/source/core/tool/scmatrix.cxx   |   78 ++++++++++++++++++++++++
 5 files changed, 269 insertions(+), 42 deletions(-)

New commits:
commit ae4dc8e0ea3b78d804d1022905501a56030073c0
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Jan 8 01:56:46 2014 +0100

    resolved fdo#72929 buffer jump matrix' result matrix blocks

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 93105dd..1db1641 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -269,6 +269,18 @@ public:
     void FillDouble( double fVal,
             SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 );
 
+    /** 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 );
+
+    /** 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 );
+
+    /** Put a column vector of empties, starting at row nR, must fit into dimensions. */
+    void PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR );
+
+    /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */
+    void PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR );
+
     /** 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!
diff --git a/sc/source/core/inc/jumpmatrix.hxx b/sc/source/core/inc/jumpmatrix.hxx
index 30391f9..959a865 100644
--- a/sc/source/core/inc/jumpmatrix.hxx
+++ b/sc/source/core/inc/jumpmatrix.hxx
@@ -67,6 +67,29 @@ class ScJumpMatrix
     SCSIZE              nResMatRows;
     bool                bStarted;
 
+    // Buffer result ranges to be able to set a range of identically typed
+    // values at the result matrix in order to avoid multiple shrinks and
+    // growths of multi_type_vector segments, which is a major performance
+    // bottleneck, see fdo#72929
+    ::std::vector< svl::SharedString >  mvBufferStrings;
+    ::std::vector< double >             mvBufferDoubles;
+    SCSIZE                              mnBufferCol;
+    SCSIZE                              mnBufferRowStart;
+    SCSIZE                              mnBufferEmptyCount;
+    SCSIZE                              mnBufferEmptyPathCount;
+
+    enum BufferType
+    {
+        BUFFER_NONE,
+        BUFFER_DOUBLE,
+        BUFFER_STRING,
+        BUFFER_EMPTY,
+        BUFFER_EMPTYPATH
+    };
+
+    /** Flush different types or non-consecutive buffers. */
+    void FlushBufferOtherThan( BufferType eType, SCSIZE nC, SCSIZE nR );
+
     // not implemented, prevent usage
     ScJumpMatrix( const ScJumpMatrix& );
     ScJumpMatrix& operator=( const ScJumpMatrix& );
@@ -80,11 +103,17 @@ public:
     void SetAllJumps( double fBool, short nStart, short nNext, short nStop = SHRT_MAX );
     void SetJumpParameters( ScTokenVec* p );
     const ScTokenVec* GetJumpParameters() const;
-    ScMatrix* GetResultMatrix() const;
+    bool HasResultMatrix() const;
+    ScMatrix* GetResultMatrix();        ///< also applies pending buffered values
     void GetPos( SCSIZE& rCol, SCSIZE& rRow ) const;
     bool Next( SCSIZE& rCol, SCSIZE& rRow );
     void GetResMatDimensions( SCSIZE& rCols, SCSIZE& rRows );
     void SetNewResMat( SCSIZE nNewCols, SCSIZE nNewRows );
+
+    void PutResultDouble( double fVal, SCSIZE nC, SCSIZE nR );
+    void PutResultString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR );
+    void PutResultEmpty( SCSIZE nC, SCSIZE nR );
+    void PutResultEmptyPath( SCSIZE nC, SCSIZE nR );
 };
 
 #endif // SC_JUMPMATRIX_HXX
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index bf32280..d9d1867 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -216,20 +216,20 @@ void ScInterpreter::ScIfJump()
     is the result matrix of a jump matrix. All arguments must be valid and are
     not checked. */
 static void lcl_storeJumpMatResult(
-    const ScMatrix* pMat, ScMatrix* pResMat, SCSIZE nC, SCSIZE nR )
+    const ScMatrix* pMat, ScJumpMatrix* pJumpMat, SCSIZE nC, SCSIZE nR )
 {
     if ( pMat->IsValue( nC, nR ) )
     {
         double fVal = pMat->GetDouble( nC, nR );
-        pResMat->PutDouble( fVal, nC, nR );
+        pJumpMat->PutResultDouble( fVal, nC, nR );
     }
     else if ( pMat->IsEmpty( nC, nR ) )
     {
-        pResMat->PutEmpty( nC, nR );
+        pJumpMat->PutResultEmpty( nC, nR );
     }
     else
     {
-        pResMat->PutString(pMat->GetString(nC, nR), nC, nR);
+        pJumpMat->PutResultString(pMat->GetString(nC, nR), nC, nR);
     }
 }
 
@@ -334,7 +334,6 @@ void ScInterpreter::ScIfError( bool bNAonly )
                 {
                     const ScMatrix* pMatPtr = pMat.get();
                     ScJumpMatrix* pJumpMat = new ScJumpMatrix( nCols, nRows );
-                    ScMatrix* pResMatPtr = pJumpMat->GetResultMatrix();
                     // Init all jumps to no error to save single calls. Error
                     // is the exceptional condition.
                     const double fFlagResult = CreateDoubleError( errJumpMatHasResult);
@@ -346,7 +345,7 @@ void ScInterpreter::ScIfError( bool bNAonly )
                     {
                         for ( ; nR < nRows && (nC != nErrorCol || nR != nErrorRow); ++nR)
                         {
-                            lcl_storeJumpMatResult(pMatPtr, pResMatPtr, nC, nR);
+                            lcl_storeJumpMatResult(pMatPtr, pJumpMat, nC, nR);
                         }
                         if (nC != nErrorCol || nR != nErrorRow)
                             ++nC;
@@ -363,7 +362,7 @@ void ScInterpreter::ScIfError( bool bNAonly )
                             }
                             else
                             {   // FALSE, EMPTY path, store result instead
-                                lcl_storeJumpMatResult(pMatPtr, pResMatPtr, nC, nR);
+                                lcl_storeJumpMatResult(pMatPtr, pJumpMat, nC, nR);
                             }
                         }
                     }
@@ -492,7 +491,7 @@ void ScInterpreter::ScChoseJump()
         aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
 }
 
-static void lcl_AdjustJumpMatrix( ScJumpMatrix* pJumpM, ScMatrixRef& pResMat, SCSIZE nParmCols, SCSIZE nParmRows )
+static void lcl_AdjustJumpMatrix( ScJumpMatrix* pJumpM, SCSIZE nParmCols, SCSIZE nParmRows )
 {
     SCSIZE nJumpCols, nJumpRows;
     SCSIZE nResCols, nResRows;
@@ -518,14 +517,13 @@ static void lcl_AdjustJumpMatrix( ScJumpMatrix* pJumpM, ScMatrixRef& pResMat, SC
             nAdjustRows = nParmRows;
         }
         pJumpM->SetNewResMat( nAdjustCols, nAdjustRows );
-        pResMat = pJumpM->GetResultMatrix();
     }
 }
 
 bool ScInterpreter::JumpMatrix( short nStackLevel )
 {
     pJumpMatrix = static_cast<ScToken*>(pStack[sp-nStackLevel])->GetJumpMatrix();
-    ScMatrixRef pResMat = pJumpMatrix->GetResultMatrix();
+    bool bHasResMat = pJumpMatrix->HasResultMatrix();
     SCSIZE nC, nR;
     if ( nStackLevel == 2 )
     {
@@ -536,7 +534,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
             OSL_FAIL( "ScInterpreter::JumpMatrix: pop goes the weasel" );
         }
 
-        if ( !pResMat )
+        if ( !bHasResMat )
         {
             Pop();
             SetError( errUnknownStackVariable );
@@ -554,7 +552,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                         fVal = CreateDoubleError( nGlobalError );
                         nGlobalError = 0;
                     }
-                    pResMat->PutDouble( fVal, nC, nR );
+                    pJumpMatrix->PutResultDouble( fVal, nC, nR );
                 }
                 break;
                 case svString:
@@ -562,12 +560,12 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                     svl::SharedString aStr = GetString();
                     if ( nGlobalError )
                     {
-                        pResMat->PutDouble( CreateDoubleError( nGlobalError),
+                        pJumpMatrix->PutResultDouble( CreateDoubleError( nGlobalError),
                                 nC, nR);
                         nGlobalError = 0;
                     }
                     else
-                        pResMat->PutString(aStr, nC, nR);
+                        pJumpMatrix->PutResultString(aStr, nC, nR);
                 }
                 break;
                 case svSingleRef:
@@ -576,7 +574,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                     PopSingleRef( aAdr );
                     if ( nGlobalError )
                     {
-                        pResMat->PutDouble( CreateDoubleError( nGlobalError),
+                        pJumpMatrix->PutResultDouble( CreateDoubleError( nGlobalError),
                                 nC, nR);
                         nGlobalError = 0;
                     }
@@ -585,7 +583,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                         ScRefCellValue aCell;
                         aCell.assign(*pDok, aAdr);
                         if (aCell.hasEmptyValue())
-                            pResMat->PutEmpty( nC, nR );
+                            pJumpMatrix->PutResultEmpty( nC, nR );
                         else if (aCell.hasNumeric())
                         {
                             double fVal = GetCellValue(aAdr, aCell);
@@ -595,7 +593,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                                         nGlobalError);
                                 nGlobalError = 0;
                             }
-                            pResMat->PutDouble( fVal, nC, nR );
+                            pJumpMatrix->PutResultDouble( fVal, nC, nR );
                         }
                         else
                         {
@@ -603,12 +601,12 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                             GetCellString(aStr, aCell);
                             if ( nGlobalError )
                             {
-                                pResMat->PutDouble( CreateDoubleError(
+                                pJumpMatrix->PutResultDouble( CreateDoubleError(
                                             nGlobalError), nC, nR);
                                 nGlobalError = 0;
                             }
                             else
-                                pResMat->PutString(aStr, nC, nR);
+                                pJumpMatrix->PutResultString(aStr, nC, nR);
                         }
                     }
                 }
@@ -622,7 +620,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                     {
                         fVal = CreateDoubleError( nGlobalError );
                         nGlobalError = 0;
-                        pResMat->PutDouble( fVal, nC, nR );
+                        pJumpMatrix->PutResultDouble( fVal, nC, nR );
                     }
                     else
                     {
@@ -637,7 +635,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                                     aRange.aEnd.Row() != aRange.aStart.Row()))
                           {
                             fVal = CreateDoubleError( NOTAVAILABLE );
-                            pResMat->PutDouble( fVal, nC, nR );
+                            pJumpMatrix->PutResultDouble( fVal, nC, nR );
                           }
                           else
                           {
@@ -653,7 +651,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                             ScRefCellValue aCell;
                             aCell.assign(*pDok, aAdr);
                             if (aCell.hasEmptyValue())
-                                pResMat->PutEmpty( nC, nR );
+                                pJumpMatrix->PutResultEmpty( nC, nR );
                             else if (aCell.hasNumeric())
                               {
                                 double fCellVal = GetCellValue(aAdr, aCell);
@@ -663,7 +661,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                                             nGlobalError);
                                     nGlobalError = 0;
                                 }
-                                pResMat->PutDouble( fCellVal, nC, nR );
+                                pJumpMatrix->PutResultDouble( fCellVal, nC, nR );
                               }
                               else
                               {
@@ -671,17 +669,17 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                                 GetCellString(aStr, aCell);
                                 if ( nGlobalError )
                                 {
-                                    pResMat->PutDouble( CreateDoubleError(
+                                    pJumpMatrix->PutResultDouble( CreateDoubleError(
                                                 nGlobalError), nC, nR);
                                     nGlobalError = 0;
                                 }
                                 else
-                                    pResMat->PutString(aStr, nC, nR);
+                                    pJumpMatrix->PutResultString(aStr, nC, nR);
                             }
                           }
                         SCSIZE nParmCols = aRange.aEnd.Col() - aRange.aStart.Col() + 1;
                         SCSIZE nParmRows = aRange.aEnd.Row() - aRange.aStart.Row() + 1;
-                        lcl_AdjustJumpMatrix( pJumpMatrix, pResMat, nParmCols, nParmRows );
+                        lcl_AdjustJumpMatrix( pJumpMatrix, nParmCols, nParmRows );
                     }
                 }
                 break;
@@ -693,12 +691,12 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                     {
                         fVal = CreateDoubleError( nGlobalError );
                         nGlobalError = 0;
-                        pResMat->PutDouble( fVal, nC, nR );
+                        pJumpMatrix->PutResultDouble( fVal, nC, nR );
                     }
                     else if ( !pMat )
                     {
                         fVal = CreateDoubleError( errUnknownVariable );
-                        pResMat->PutDouble( fVal, nC, nR );
+                        pJumpMatrix->PutResultDouble( fVal, nC, nR );
                     }
                     else
                     {
@@ -708,13 +706,13 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                             (nRows <= nR && nRows != 1))
                         {
                             fVal = CreateDoubleError( NOTAVAILABLE );
-                            pResMat->PutDouble( fVal, nC, nR );
+                            pJumpMatrix->PutResultDouble( fVal, nC, nR );
                         }
                         else
                         {
-                            lcl_storeJumpMatResult(pMat.get(), pResMat.get(), nC, nR);
+                            lcl_storeJumpMatResult(pMat.get(), pJumpMatrix, nC, nR);
                         }
-                        lcl_AdjustJumpMatrix( pJumpMatrix, pResMat, nCols, nRows );
+                        lcl_AdjustJumpMatrix( pJumpMatrix, nCols, nRows );
                     }
                 }
                 break;
@@ -723,14 +721,14 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                     PopError();
                     double fVal = CreateDoubleError( nGlobalError);
                     nGlobalError = 0;
-                    pResMat->PutDouble( fVal, nC, nR );
+                    pJumpMatrix->PutResultDouble( fVal, nC, nR );
                 }
                 break;
                 default:
                 {
                     Pop();
                     double fVal = CreateDoubleError( errIllegalArgument);
-                    pResMat->PutDouble( fVal, nC, nR );
+                    pJumpMatrix->PutResultDouble( fVal, nC, nR );
                 }
             }
         }
@@ -743,13 +741,13 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
         pJumpMatrix->GetJump( nC, nR, fBool, nStart, nNext, nStop );
         while ( bCont && nStart == nNext )
         {   // push all results that have no jump path
-            if ( pResMat && (GetDoubleErrorValue( fBool) != errJumpMatHasResult) )
+            if ( bHasResMat && (GetDoubleErrorValue( fBool) != errJumpMatHasResult) )
             {
                 // a false without path results in an empty path value
                 if ( fBool == 0.0 )
-                    pResMat->PutEmptyPath( nC, nR );
+                    pJumpMatrix->PutResultEmptyPath( nC, nR );
                 else
-                    pResMat->PutDouble( fBool, nC, nR );
+                    pJumpMatrix->PutResultDouble( fBool, nC, nR );
             }
             bCont = pJumpMatrix->Next( nC, nR );
             if ( bCont )
@@ -774,6 +772,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
     }
     if ( !bCont )
     {   // we're done with it, throw away jump matrix, keep result
+        ScMatrix* pResMat = pJumpMatrix->GetResultMatrix();
         pJumpMatrix = NULL;
         Pop();
         PushMatrix( pResMat );
diff --git a/sc/source/core/tool/jumpmatrix.cxx b/sc/source/core/tool/jumpmatrix.cxx
index 6a8b4a7..adac4f6 100644
--- a/sc/source/core/tool/jumpmatrix.cxx
+++ b/sc/source/core/tool/jumpmatrix.cxx
@@ -20,6 +20,11 @@
 #include "jumpmatrix.hxx"
 #include "scmatrix.hxx"
 
+namespace {
+// Don't bother with buffer overhead for less than y rows.
+const SCSIZE kBufferThreshhold = 128;
+}
+
 ScJumpMatrix::ScJumpMatrix(SCSIZE nColsP, SCSIZE nRowsP)
     : pJump(new ScJumpMatrixEntry[nColsP * nRowsP])
     , pMat(new ScMatrix(nColsP, nRowsP))
@@ -31,6 +36,10 @@ ScJumpMatrix::ScJumpMatrix(SCSIZE nColsP, SCSIZE nRowsP)
     , nResMatCols(nColsP)
     , nResMatRows(nRowsP)
     , bStarted(false)
+    , mnBufferCol(0)
+    , mnBufferRowStart(0)
+    , mnBufferEmptyCount(0)
+    , mnBufferEmptyPathCount(0)
 {
     // Initialize result matrix in case of
     // a premature end of the interpreter
@@ -106,11 +115,6 @@ const ScTokenVec* ScJumpMatrix::GetJumpParameters() const
     return pParams;
 }
 
-ScMatrix* ScJumpMatrix::GetResultMatrix() const
-{
-    return pMat.get();
-}
-
 void ScJumpMatrix::GetPos(SCSIZE& rCol, SCSIZE& rRow) const
 {
     rCol = nCurCol;
@@ -146,6 +150,7 @@ void ScJumpMatrix::SetNewResMat(SCSIZE nNewCols, SCSIZE nNewRows)
 {
     if (nNewCols > nResMatCols || nNewRows > nResMatRows)
     {
+        FlushBufferOtherThan( BUFFER_NONE, 0, 0);
         pMat = pMat->CloneAndExtend(nNewCols, nNewRows);
         if (nResMatCols < nNewCols)
         {
@@ -169,5 +174,109 @@ void ScJumpMatrix::SetNewResMat(SCSIZE nNewCols, SCSIZE nNewRows)
     }
 }
 
+bool ScJumpMatrix::HasResultMatrix() const
+{
+    // We now always have a matrix but caller logic may still want to check it.
+    return pMat.get() != NULL;
+}
+
+void ScJumpMatrix::FlushBufferOtherThan( ScJumpMatrix::BufferType eType, SCSIZE nC, SCSIZE nR )
+{
+    if (!mvBufferDoubles.empty() &&
+            (eType != BUFFER_DOUBLE || nC != mnBufferCol || nR != mnBufferRowStart + mvBufferDoubles.size()))
+    {
+        pMat->PutDoubleVector( mvBufferDoubles, mnBufferCol, mnBufferRowStart);
+        mvBufferDoubles.clear();
+    }
+    if (!mvBufferStrings.empty() &&
+            (eType != BUFFER_STRING || nC != mnBufferCol || nR != mnBufferRowStart + mvBufferStrings.size()))
+    {
+        pMat->PutStringVector( mvBufferStrings, mnBufferCol, mnBufferRowStart);
+        mvBufferStrings.clear();
+    }
+    if (mnBufferEmptyCount &&
+            (eType != BUFFER_EMPTY || nC != mnBufferCol || nR != mnBufferRowStart + mnBufferEmptyCount))
+    {
+        pMat->PutEmptyVector( mnBufferEmptyCount, mnBufferCol, mnBufferRowStart);
+        mnBufferEmptyCount = 0;
+    }
+    if (mnBufferEmptyPathCount &&
+            (eType != BUFFER_EMPTYPATH || nC != mnBufferCol || nR != mnBufferRowStart + mnBufferEmptyPathCount))
+    {
+        pMat->PutEmptyPathVector( mnBufferEmptyPathCount, mnBufferCol, mnBufferRowStart);
+        mnBufferEmptyPathCount = 0;
+    }
+}
+
+ScMatrix* ScJumpMatrix::GetResultMatrix()
+{
+    if (nResMatRows >= kBufferThreshhold)
+        FlushBufferOtherThan( BUFFER_NONE, 0, 0);
+    return pMat.get();
+}
+
+void ScJumpMatrix::PutResultDouble( double fVal, SCSIZE nC, SCSIZE nR )
+{
+    if (nResMatRows < kBufferThreshhold)
+        pMat->PutDouble( fVal, nC, nR);
+    else
+    {
+        FlushBufferOtherThan( BUFFER_DOUBLE, nC, nR);
+        if (mvBufferDoubles.empty())
+        {
+            mnBufferCol = nC;
+            mnBufferRowStart = nR;
+        }
+        mvBufferDoubles.push_back( fVal);
+    }
+}
+
+void ScJumpMatrix::PutResultString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR )
+{
+    if (nResMatRows < kBufferThreshhold)
+        pMat->PutString( rStr, nC, nR);
+    else
+    {
+        FlushBufferOtherThan( BUFFER_STRING, nC, nR);
+        if (mvBufferStrings.empty())
+        {
+            mnBufferCol = nC;
+            mnBufferRowStart = nR;
+        }
+        mvBufferStrings.push_back( rStr);
+    }
+}
+
+void ScJumpMatrix::PutResultEmpty( SCSIZE nC, SCSIZE nR )
+{
+    if (nResMatRows < kBufferThreshhold)
+        pMat->PutEmpty( nC, nR);
+    else
+    {
+        FlushBufferOtherThan( BUFFER_EMPTY, nC, nR);
+        if (!mnBufferEmptyCount)
+        {
+            mnBufferCol = nC;
+            mnBufferRowStart = nR;
+        }
+        ++mnBufferEmptyCount;
+    }
+}
+
+void ScJumpMatrix::PutResultEmptyPath( SCSIZE nC, SCSIZE nR )
+{
+    if (nResMatRows < kBufferThreshhold)
+        pMat->PutEmptyPath( nC, nR);
+    else
+    {
+        FlushBufferOtherThan( BUFFER_EMPTYPATH, nC, nR);
+        if (!mnBufferEmptyPathCount)
+        {
+            mnBufferCol = nC;
+            mnBufferRowStart = nR;
+        }
+        ++mnBufferEmptyPathCount;
+    }
+}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 1a5ebbb..132923d 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -252,6 +252,10 @@ public:
     void MatCopy(ScMatrixImpl& mRes) const;
     void MatTrans(ScMatrixImpl& mRes) const;
     void FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 );
+    void PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR );
+    void PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR );
+    void PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR );
+    void PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR );
     void CompareEqual();
     void CompareNotEqual();
     void CompareLess();
@@ -764,6 +768,60 @@ void ScMatrixImpl::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2,
     }
 }
 
+void ScMatrixImpl::PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR )
+{
+    if (!rVec.empty() && ValidColRow( nC, nR) && ValidColRow( nC, nR + rVec.size() - 1))
+    {
+        maMat.set(nR, nC, rVec.begin(), rVec.end());
+    }
+    else
+    {
+        OSL_FAIL("ScMatrixImpl::PutDoubleVector: dimension error");
+    }
+}
+
+void ScMatrixImpl::PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR )
+{
+    if (!rVec.empty() && ValidColRow( nC, nR) && ValidColRow( nC, nR + rVec.size() - 1))
+    {
+        maMat.set(nR, nC, rVec.begin(), rVec.end());
+    }
+    else
+    {
+        OSL_FAIL("ScMatrixImpl::PutStringVector: dimension error");
+    }
+}
+
+void ScMatrixImpl::PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR )
+{
+    if (nCount && ValidColRow( nC, nR) && ValidColRow( nC, nR + nCount - 1))
+    {
+        maMat.set_empty(nR, nC, nCount);
+        // zero flag to indicate that this is 'empty', not 'empty path'.
+        std::vector<bool> aVals(nCount, false);
+        maMatFlag.set(nR, nC, aVals.begin(), aVals.end());
+    }
+    else
+    {
+        OSL_FAIL("ScMatrixImpl::PutEmptyVector: dimension error");
+    }
+}
+
+void ScMatrixImpl::PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR )
+{
+    if (nCount && ValidColRow( nC, nR) && ValidColRow( nC, nR + nCount - 1))
+    {
+        maMat.set_empty(nR, nC, nCount);
+        // non-zero flag to indicate empty 'path'.
+        std::vector<bool> aVals(nCount, true);
+        maMatFlag.set(nR, nC, aVals.begin(), aVals.end());
+    }
+    else
+    {
+        OSL_FAIL("ScMatrixImpl::PutEmptyPathVector: dimension error");
+    }
+}
+
 void ScMatrixImpl::CompareEqual()
 {
     MatrixImplType::size_pair_type aSize = maMat.size();
@@ -2032,6 +2090,26 @@ void ScMatrix::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSI
     pImpl->FillDouble(fVal, nC1, nR1, nC2, nR2);
 }
 
+void ScMatrix::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 )
+{
+    pImpl->PutStringVector(rVec, nC, nR);
+}
+
+void ScMatrix::PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR )
+{
+    pImpl->PutEmptyVector(nCount, nC, nR);
+}
+
+void ScMatrix::PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR )
+{
+    pImpl->PutEmptyPathVector(nCount, nC, nR);
+}
+
 void ScMatrix::CompareEqual()
 {
     pImpl->CompareEqual();


More information about the Libreoffice-commits mailing list