summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2017-05-21 00:20:46 +0200
committerEike Rathke <erack@redhat.com>2017-05-22 11:00:56 +0200
commitf6cdba8a801ba296bd3f7ca6334fc3671b0bbe58 (patch)
treea66220c4d453993663babe68abd039efe609e7f5
parent667e0625090f084b8d9ae5a885b6b4624766ed6c (diff)
Factor out ScInterpreter::SwitchToArrayRefList(), tdf#58874
Change-Id: I7a672b8d0bd6dae9baa1289a3b00b0789a0d4d6d
-rw-r--r--sc/source/core/inc/interpre.hxx4
-rw-r--r--sc/source/core/tool/interpr1.cxx84
2 files changed, 48 insertions, 40 deletions
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 3586d21c317f..9948392ea622 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -571,6 +571,10 @@ void ScMax( bool bTextAsZero = false );
/** Check for array of references to determine the maximum size of a return
column vector if in array context. */
size_t GetRefListArrayMaxSize( short nParamCount );
+/** Switch to array reference list if current TOS is one and create/init or
+ update matrix and return true. Else return false. */
+bool SwitchToArrayRefList( ScMatrixRef& xResMat, SCSIZE nMatRows, double fCurrent,
+ const std::function<bool( double& fVectorResult, const double& fCurrent )>& AssignFunc );
void IterateParameters( ScIterFunc, bool bTextAsZero = false );
void ScSumSQ();
void ScSum();
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index bf8b9dc77c00..675e9c8165bf 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -3456,6 +3456,34 @@ void ScInterpreter::ScUnichar()
}
}
+bool ScInterpreter::SwitchToArrayRefList( ScMatrixRef& xResMat, SCSIZE nMatRows, double fCurrent,
+ const std::function<bool( double& fVectorResult, const double& fCurrent )>& AssignFunc )
+{
+ const ScRefListToken* p = dynamic_cast<const ScRefListToken*>(pStack[sp-1]);
+ if (!p || !p->IsArrayResult())
+ return false;
+
+ if (!xResMat)
+ {
+ // Create and init all elements with current value.
+ assert(nMatRows > 0);
+ xResMat = GetNewMat( 1, nMatRows, true);
+ xResMat->FillDouble( fCurrent, 0,0, 0,nMatRows-1);
+ }
+ else
+ {
+ // Current value and values from vector are operands
+ // for each vector position.
+ for (SCSIZE i=0; i < nMatRows; ++i)
+ {
+ double fVecRes = xResMat->GetDouble(0,i);
+ if (AssignFunc( fVecRes, fCurrent))
+ xResMat->PutDouble( fVecRes, 0,i);
+ }
+ }
+ return true;
+}
+
void ScInterpreter::ScMin( bool bTextAsZero )
{
short nParamCount = GetByte();
@@ -3499,29 +3527,17 @@ void ScInterpreter::ScMin( bool bTextAsZero )
break;
case svRefList :
{
- const ScRefListToken* p = dynamic_cast<const ScRefListToken*>(pStack[sp-1]);
- if (p && p->IsArrayResult())
+ auto AssignFunc = []( double& fVecRes, double fMin )
{
- nRefArrayPos = nRefInList;
- if (!xResMat)
- {
- // Create and init all elements with current value.
- assert(nMatRows > 0);
- xResMat = GetNewMat( 1, nMatRows, true);
- xResMat->FillDouble( nMin, 0,0, 0,nMatRows-1);
- }
- else
+ if (fVecRes > fMin)
{
- // Current value and values from vector are operands
- // for each vector position.
- for (SCSIZE i=0; i < nMatRows; ++i)
- {
- double fVecRes = xResMat->GetDouble(0,i);
- if (fVecRes > nMin)
- xResMat->PutDouble( nMin, 0,i);
- }
+ fVecRes = fMin;
+ return true;
}
- }
+ return false;
+ };
+ if (SwitchToArrayRefList( xResMat, nMatRows, nMin, AssignFunc))
+ nRefArrayPos = nRefInList;
}
SAL_FALLTHROUGH;
case svDoubleRef :
@@ -3666,29 +3682,17 @@ void ScInterpreter::ScMax( bool bTextAsZero )
break;
case svRefList :
{
- const ScRefListToken* p = dynamic_cast<const ScRefListToken*>(pStack[sp-1]);
- if (p && p->IsArrayResult())
+ auto AssignFunc = []( double& fVecRes, double fMax )
{
- nRefArrayPos = nRefInList;
- if (!xResMat)
+ if (fVecRes < fMax)
{
- // Create and init all elements with current value.
- assert(nMatRows > 0);
- xResMat = GetNewMat( 1, nMatRows, true);
- xResMat->FillDouble( nMax, 0,0, 0,nMatRows-1);
+ fVecRes = fMax;
+ return true;
}
- else
- {
- // Current value and values from vector are operands
- // for each vector position.
- for (SCSIZE i=0; i < nMatRows; ++i)
- {
- double fVecRes = xResMat->GetDouble(0,i);
- if (fVecRes < nMax)
- xResMat->PutDouble( nMax, 0,i);
- }
- }
- }
+ return false;
+ };
+ if (SwitchToArrayRefList( xResMat, nMatRows, nMax, AssignFunc))
+ nRefArrayPos = nRefInList;
}
SAL_FALLTHROUGH;
case svDoubleRef :