summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2014-01-08 01:56:46 +0100
committerEike Rathke <erack@redhat.com>2014-01-08 17:28:38 +0100
commitae4dc8e0ea3b78d804d1022905501a56030073c0 (patch)
tree49b4c8ed3ece9a1aa1ab4d7c0609e90de4a39fa6
parent235c790fdb04c27487de4510a0d51323f5442e70 (diff)
resolved fdo#72929 buffer jump matrix' result matrix blocks
-rw-r--r--sc/inc/scmatrix.hxx12
-rw-r--r--sc/source/core/inc/jumpmatrix.hxx31
-rw-r--r--sc/source/core/tool/interpr1.cxx71
-rw-r--r--sc/source/core/tool/jumpmatrix.cxx119
-rw-r--r--sc/source/core/tool/scmatrix.cxx78
5 files changed, 269 insertions, 42 deletions
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 93105dd316df..1db16417d7da 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 30391f94b016..959a86516c62 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 bf32280dc689..d9d18678e5b9 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 6a8b4a72fb2d..adac4f68f6a3 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 1a5ebbbdafc4..132923decf7e 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();