[Libreoffice-commits] core.git: Branch 'feature/fixes12' - cui/source cui/uiconfig officecfg/registry sc/inc sc/source
Jan Holesovsky
kendy at collabora.com
Mon Nov 30 07:50:26 PST 2015
cui/source/options/optopencl.cxx | 19
cui/source/options/optopencl.hxx | 1
cui/uiconfig/ui/optopenclpage.ui | 18
officecfg/registry/schema/org/openoffice/Office/Common.xcs | 7
sc/inc/calcconfig.hxx | 1
sc/inc/scmatrix.hxx | 19
sc/source/core/data/formulacell.cxx | 3
sc/source/core/tool/calcconfig.cxx | 6
sc/source/core/tool/formulagroup.cxx | 223 -----
sc/source/core/tool/scmatrix.cxx | 511 ++++++++-----
sc/source/core/tool/token.cxx | 10
11 files changed, 442 insertions(+), 376 deletions(-)
New commits:
commit f55d76b8a6d9f5a218f100620da29c7ea4ed00e9
Author: Jan Holesovsky <kendy at collabora.com>
Date: Mon Nov 30 12:49:02 2015 +0100
Test commit: S/W Interpreter including the UI changes.
Change-Id: Ia23c360a0db1ee2c8f6bfd8b31657405d97fcd9c
diff --git a/cui/source/options/optopencl.cxx b/cui/source/options/optopencl.cxx
index 71cd281..db1470e 100644
--- a/cui/source/options/optopencl.cxx
+++ b/cui/source/options/optopencl.cxx
@@ -35,7 +35,8 @@
#include <com/sun/star/util/XChangesBatch.hpp>
#include <com/sun/star/setup/UpdateCheckConfig.hpp>
-#include "cuires.hrc"
+#include <cuires.hrc>
+#include <dialmgr.hxx>
#include "optopencl.hxx"
#include <svtools/treelistentry.hxx>
@@ -43,6 +44,7 @@ SvxOpenCLTabPage::SvxOpenCLTabPage(vcl::Window* pParent, const SfxItemSet& rSet)
SfxTabPage(pParent, "OptOpenCLPage", "cui/ui/optopenclpage.ui", &rSet),
maConfig(OpenCLConfig::get())
{
+ get(mpUseSwInterpreter, "useswinterpreter");
get(mpUseOpenCL, "useopencl");
get(mpBlackListTable, "blacklist");
get(mpBlackListFrame,"blacklistframe");
@@ -60,6 +62,8 @@ SvxOpenCLTabPage::SvxOpenCLTabPage(vcl::Window* pParent, const SfxItemSet& rSet)
get(mpVendor,"vendor");
get(mpDrvVersion,"driverversion");
+ mpUseSwInterpreter->Check(officecfg::Office::Common::Misc::UseSwInterpreter::get());
+
mpUseOpenCL->Check(maConfig.mbUseOpenCL);
mpUseOpenCL->SetClickHdl(LINK(this, SvxOpenCLTabPage, EnableOpenCLHdl));
@@ -116,6 +120,7 @@ void SvxOpenCLTabPage::dispose()
mpBlackList.disposeAndClear();
mpWhiteList.disposeAndClear();
+ mpUseSwInterpreter.clear();
mpUseOpenCL.clear();
mpBlackListFrame.clear();
mpBlackListTable.clear();
@@ -146,6 +151,15 @@ bool SvxOpenCLTabPage::FillItemSet( SfxItemSet* )
bool bModified = false;
std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ if (mpUseSwInterpreter->IsValueChangedFromSaved())
+ {
+ officecfg::Office::Common::Misc::UseSwInterpreter::set(mpUseSwInterpreter->IsChecked(), batch);
+ bModified = true;
+
+ ScopedVclPtrInstance<MessageDialog> aWarnBox(this, CUI_RES(RID_SVXSTR_OPTIONS_RESTART), VCL_MESSAGE_INFO);
+ aWarnBox->Execute();
+ }
+
if (mpUseOpenCL->IsValueChangedFromSaved())
maConfig.mbUseOpenCL = mpUseOpenCL->IsChecked();
@@ -195,6 +209,9 @@ void SvxOpenCLTabPage::Reset( const SfxItemSet* )
{
maConfig = OpenCLConfig::get();
+ mpUseSwInterpreter->Check(officecfg::Office::Common::Misc::UseSwInterpreter::get());
+ mpUseSwInterpreter->SaveValue();
+
mpUseOpenCL->Check(maConfig.mbUseOpenCL);
mpUseOpenCL->SaveValue();
diff --git a/cui/source/options/optopencl.hxx b/cui/source/options/optopencl.hxx
index fe91fe1..10dc30b 100644
--- a/cui/source/options/optopencl.hxx
+++ b/cui/source/options/optopencl.hxx
@@ -31,6 +31,7 @@ class SvxOpenCLTabPage : public SfxTabPage
private:
OpenCLConfig maConfig;
+ VclPtr<CheckBox> mpUseSwInterpreter;
VclPtr<CheckBox> mpUseOpenCL;
VclPtr<VclFrame> mpBlackListFrame;
diff --git a/cui/uiconfig/ui/optopenclpage.ui b/cui/uiconfig/ui/optopenclpage.ui
index 89ac882..2cad763 100644
--- a/cui/uiconfig/ui/optopenclpage.ui
+++ b/cui/uiconfig/ui/optopenclpage.ui
@@ -26,6 +26,22 @@
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
+ <object class="GtkCheckButton" id="useswinterpreter">
+ <property name="label" translatable="yes">Allow use of Software Interpreter (even when OpenCL is not available)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkCheckButton" id="useopencl">
<property name="label" translatable="yes">Allow use of OpenCL</property>
<property name="visible">True</property>
@@ -38,7 +54,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
index d693fc7..800ac71 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -5642,6 +5642,13 @@
</info>
<value oor:separator=";">Linux//Advanced Micro Devices, Inc\.//1445\.5 \(sse2,avx\);//Advanced Micro Devices, Inc\.//;//Intel\(R\) Corporation//;//NVIDIA Corporation//</value>
</prop>
+ <prop oor:name="UseSwInterpreter" oor:type="xs:boolean" oor:nillable="false">
+ <info>
+ <desc>Determines whether Software Interpreter can be used to speed
+ up some operations on Calc formulas.</desc>
+ </info>
+ <value>true</value>
+ </prop>
<prop oor:name="MacroRecorderMode" oor:type="xs:boolean" oor:nillable="false">
<info>
<desc>Determines if the limited, and awkward code producing
diff --git a/sc/inc/calcconfig.hxx b/sc/inc/calcconfig.hxx
index ec355cf..eaf4f36 100644
--- a/sc/inc/calcconfig.hxx
+++ b/sc/inc/calcconfig.hxx
@@ -49,6 +49,7 @@ struct SC_DLLPUBLIC ScCalcConfig
bool mbHasStringRefSyntax:1;
static bool isOpenCLEnabled();
+ static bool isSwInterpreterEnabled();
bool mbOpenCLSubsetOnly:1;
bool mbOpenCLAutoSelect:1;
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index a6c6d96..1cea9c9 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -409,9 +409,6 @@ class SC_DLLPUBLIC ScFullMatrix : public ScMatrix
ScMatrixImpl* pImpl;
- // only delete via Delete()
- virtual ~ScFullMatrix();
-
ScFullMatrix( const ScFullMatrix& ) = delete;
ScFullMatrix& operator=( const ScFullMatrix&) = delete;
@@ -422,6 +419,8 @@ public:
ScFullMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals );
+ virtual ~ScFullMatrix();
+
/** Clone the matrix. */
virtual ScMatrix* Clone() const override;
@@ -611,19 +610,27 @@ class SC_DLLPUBLIC ScVectorRefMatrix : public ScMatrix
const formula::DoubleVectorRefToken* mpToken;
ScInterpreter* mpErrorInterpreter;
+ /// For the operations that are not fully implemented, create a ScFullMatrix, and operate on it.
+ std::unique_ptr<ScFullMatrix> mpFullMatrix;
+
SCSIZE mnRowStart;
SCSIZE mnRowSize;
- // only delete via Delete()
- virtual ~ScVectorRefMatrix();
-
ScVectorRefMatrix( const ScVectorRefMatrix& ) = delete;
ScVectorRefMatrix& operator=( const ScVectorRefMatrix&) = delete;
+ /// For the operations that are not fully implemented, create a ScFullMatrix, and operate on it.
+ ///
+ /// Note: This is potentially an expensive operation.
+ /// TODO: Implement as much as possible directly using the DoubleVectorRefToken.
+ void ensureFullMatrix();
+
public:
ScVectorRefMatrix(const formula::DoubleVectorRefToken* pToken, SCSIZE nRowStart, SCSIZE nRowSize);
+ virtual ~ScVectorRefMatrix();
+
/** Clone the matrix. */
virtual ScMatrix* Clone() const override;
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 66c0c40..1e3f740 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3879,6 +3879,9 @@ bool ScFormulaCell::InterpretFormulaGroup()
return false;
}
+ if (!ScCalcConfig::isOpenCLEnabled() && !ScCalcConfig::isSwInterpreterEnabled())
+ return false;
+
// TODO : Disable invariant formula group interpretation for now in order
// to get implicit intersection to work.
if (mxGroup->mbInvariant && false)
diff --git a/sc/source/core/tool/calcconfig.cxx b/sc/source/core/tool/calcconfig.cxx
index f285e13..96277ce 100644
--- a/sc/source/core/tool/calcconfig.cxx
+++ b/sc/source/core/tool/calcconfig.cxx
@@ -38,6 +38,12 @@ bool ScCalcConfig::isOpenCLEnabled()
return gOpenCLEnabled.get();
}
+bool ScCalcConfig::isSwInterpreterEnabled()
+{
+ static comphelper::ConfigurationListenerProperty<bool> gSwInterpreterEnabled(getMiscListener(), OUString("UseSwInterpreter"));
+ return gSwInterpreterEnabled.get();
+}
+
ScCalcConfig::ScCalcConfig() :
meStringRefAddressSyntax(formula::FormulaGrammar::CONV_UNSPECIFIED),
meStringConversion(StringConversion::LOCALE), // old LibreOffice behavior
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index 4369623..554aa48 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -138,156 +138,6 @@ FormulaGroupContext::~FormulaGroupContext()
{
}
-namespace {
-
-/**
- * Input double array consists of segments of NaN's and normal values.
- * Insert only the normal values into the matrix while skipping the NaN's.
- */
-void fillMatrix( ScMatrix& rMat, size_t nCol, const double* pNums, size_t nLen )
-{
- const double* pNum = pNums;
- const double* pNumEnd = pNum + nLen;
- const double* pNumHead = nullptr;
- for (; pNum != pNumEnd; ++pNum)
- {
- if (!rtl::math::isNan(*pNum))
- {
- if (!pNumHead)
- // Store the first non-NaN position.
- pNumHead = pNum;
-
- continue;
- }
-
- if (pNumHead)
- {
- // Flush this non-NaN segment to the matrix.
- rMat.PutDouble(pNumHead, pNum - pNumHead, nCol, pNumHead - pNums);
- pNumHead = nullptr;
- }
- }
-
- if (pNumHead)
- {
- // Flush last non-NaN segment to the matrix.
- rMat.PutDouble(pNumHead, pNum - pNumHead, nCol, pNumHead - pNums);
- }
-}
-
-void flushStrSegment(
- ScMatrix& rMat, size_t nCol, rtl_uString** pHead, rtl_uString** pCur, rtl_uString** pTop )
-{
- size_t nOffset = pHead - pTop;
- std::vector<svl::SharedString> aStrs;
- aStrs.reserve(pCur - pHead);
- for (; pHead != pCur; ++pHead)
- aStrs.push_back(svl::SharedString(*pHead, *pHead));
-
- rMat.PutString(&aStrs[0], aStrs.size(), nCol, nOffset);
-}
-
-void fillMatrix( ScMatrix& rMat, size_t nCol, rtl_uString** pStrs, size_t nLen )
-{
- rtl_uString** p = pStrs;
- rtl_uString** pEnd = p + nLen;
- rtl_uString** pHead = nullptr;
- for (; p != pEnd; ++p)
- {
- if (*p)
- {
- if (!pHead)
- // Store the first non-empty string position.
- pHead = p;
-
- continue;
- }
-
- if (pHead)
- {
- // Flush this non-empty segment to the matrix.
- flushStrSegment(rMat, nCol, pHead, p, pStrs);
- pHead = nullptr;
- }
- }
-
- if (pHead)
- {
- // Flush last non-empty segment to the matrix.
- flushStrSegment(rMat, nCol, pHead, p, pStrs);
- }
-}
-
-void fillMatrix( ScMatrix& rMat, size_t nCol, const double* pNums, rtl_uString** pStrs, size_t nLen )
-{
- if (!pStrs)
- {
- fillMatrix(rMat, nCol, pNums, nLen);
- return;
- }
-
- const double* pNum = pNums;
- const double* pNumHead = nullptr;
- rtl_uString** pStr = pStrs;
- rtl_uString** pStrEnd = pStr + nLen;
- rtl_uString** pStrHead = nullptr;
-
- for (; pStr != pStrEnd; ++pStr, ++pNum)
- {
- if (*pStr)
- {
- // String cell exists.
-
- if (pNumHead)
- {
- // Flush this numeric segment to the matrix.
- rMat.PutDouble(pNumHead, pNum - pNumHead, nCol, pNumHead - pNums);
- pNumHead = nullptr;
- }
-
- if (!pStrHead)
- // Store the first non-empty string position.
- pStrHead = pStr;
-
- continue;
- }
-
- // No string cell. Check the numeric cell value.
-
- if (pStrHead)
- {
- // Flush this non-empty string segment to the matrix.
- flushStrSegment(rMat, nCol, pStrHead, pStr, pStrs);
- pStrHead = nullptr;
- }
-
- if (!rtl::math::isNan(*pNum))
- {
- // Numeric cell exists.
- if (!pNumHead)
- // Store the first non-NaN position.
- pNumHead = pNum;
-
- continue;
- }
-
- // Empty cell. No action required.
- }
-
- if (pStrHead)
- {
- // Flush the last non-empty segment to the matrix.
- flushStrSegment(rMat, nCol, pStrHead, pStr, pStrs);
- }
- else if (pNumHead)
- {
- // Flush the last numeric segment to the matrix.
- rMat.PutDouble(pNumHead, pNum - pNumHead, nCol, pNumHead - pNums);
- }
-}
-
-}
-
CompiledFormula::CompiledFormula() {}
CompiledFormula::~CompiledFormula() {}
@@ -369,8 +219,6 @@ 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())
@@ -379,50 +227,6 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
assert(nRowStart <= nRowEnd);
ScMatrixRef pMat(new ScVectorRefMatrix(p2, nRowStart, nRowEnd - nRowStart + 1));
- /*
- 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)
- {
- const formula::VectorRefArray& rArray = rArrays[nCol];
- if (rArray.mpStringArray)
- {
- 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 if (rArray.mpNumericArray)
- {
- // Numeric cells only.
- const double* pNums = rArray.mpNumericArray;
- pNums += nRowStart;
- fillMatrix(*pMat, nCol, pNums, nRowSize);
- }
- }
- */
-
if (p2->IsStartFixed() && p2->IsEndFixed())
{
// Cached the converted token for absolute range reference.
@@ -477,13 +281,14 @@ FormulaGroupInterpreter *FormulaGroupInterpreter::getStatic()
if ( !msInstance )
{
#if HAVE_FEATURE_OPENCL
- const ScCalcConfig& rConfig = ScInterpreter::GetGlobalConfig();
if (ScCalcConfig::isOpenCLEnabled())
+ {
+ const ScCalcConfig& rConfig = ScInterpreter::GetGlobalConfig();
switchOpenCLDevice(rConfig.maOpenCLDevice, rConfig.mbOpenCLAutoSelect);
+ }
#endif
- static bool bAllowSoftwareInterpreter = true;
- if ( !msInstance && bAllowSoftwareInterpreter ) // software fallback
+ if (!msInstance && ScCalcConfig::isSwInterpreterEnabled()) // software interpreter
{
SAL_INFO("sc.formulagroup", "Create S/W interpreter");
msInstance = new sc::FormulaGroupInterpreterSoftware();
@@ -505,20 +310,26 @@ void FormulaGroupInterpreter::fillOpenCLInfo(std::vector<OpenCLPlatformInfo>& rP
bool FormulaGroupInterpreter::switchOpenCLDevice(const OUString& rDeviceId, bool bAutoSelect, bool bForceEvaluation)
{
bool bOpenCLEnabled = ScCalcConfig::isOpenCLEnabled();
- static bool bAllowSoftwareInterpreter = true;
- if (!bOpenCLEnabled || (bAllowSoftwareInterpreter && rDeviceId == OPENCL_SOFTWARE_DEVICE_CONFIG_NAME))
+ if (!bOpenCLEnabled || (rDeviceId == OPENCL_SOFTWARE_DEVICE_CONFIG_NAME))
{
- if(msInstance)
+ bool bSwInterpreterEnabled = ScCalcConfig::isSwInterpreterEnabled();
+ if (msInstance)
{
// if we already have a software interpreter don't delete it
- if(dynamic_cast<sc::FormulaGroupInterpreterSoftware*>(msInstance))
+ if (bSwInterpreterEnabled && dynamic_cast<sc::FormulaGroupInterpreterSoftware*>(msInstance))
return true;
delete msInstance;
+ msInstance = nullptr;
}
- msInstance = new sc::FormulaGroupInterpreterSoftware();
- return true;
+ if (bSwInterpreterEnabled)
+ {
+ msInstance = new sc::FormulaGroupInterpreterSoftware();
+ return true;
+ }
+
+ return false;
}
bool bSuccess = ::opencl::switchOpenCLDevice(&rDeviceId, bAutoSelect, bForceEvaluation);
if(!bSuccess)
@@ -527,7 +338,7 @@ bool FormulaGroupInterpreter::switchOpenCLDevice(const OUString& rDeviceId, bool
delete msInstance;
msInstance = nullptr;
- if (ScCalcConfig::isOpenCLEnabled())
+ if (bOpenCLEnabled)
{
msInstance = new sc::opencl::FormulaGroupInterpreterOpenCL();
return msInstance != nullptr;
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index aa86383..1d38318 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -1005,7 +1005,6 @@ class WalkElementBlocks
bool mbFirst:1;
bool mbTextAsZero:1;
public:
- // TODO add here also the beginning of the iteration
WalkElementBlocks(bool bTextAsZero) : maRes(_Op::InitVal, _Op::InitVal, 0), mbFirst(true), mbTextAsZero(bTextAsZero) {}
const ScMatrix::IterateResult& getResult() const { return maRes; }
@@ -1018,8 +1017,6 @@ public:
{
typedef MatrixImplType::numeric_block_type block_type;
- // TODO do here the same thing as Michael / Quikee did in
- // interpr6.cxx - see NumericCellAccumulator
block_type::const_iterator it = block_type::begin(*node.data);
block_type::const_iterator itEnd = block_type::end(*node.data);
for (; it != itEnd; ++it)
@@ -2839,6 +2836,197 @@ void ScFullMatrix::Dump() const
}
#endif
+namespace {
+
+/**
+ * Input double array consists of segments of NaN's and normal values.
+ * Insert only the normal values into the matrix while skipping the NaN's.
+ */
+void fillMatrix( ScMatrix& rMat, size_t nCol, const double* pNums, size_t nLen )
+{
+ const double* pNum = pNums;
+ const double* pNumEnd = pNum + nLen;
+ const double* pNumHead = nullptr;
+ for (; pNum != pNumEnd; ++pNum)
+ {
+ if (!rtl::math::isNan(*pNum))
+ {
+ if (!pNumHead)
+ // Store the first non-NaN position.
+ pNumHead = pNum;
+
+ continue;
+ }
+
+ if (pNumHead)
+ {
+ // Flush this non-NaN segment to the matrix.
+ rMat.PutDouble(pNumHead, pNum - pNumHead, nCol, pNumHead - pNums);
+ pNumHead = nullptr;
+ }
+ }
+
+ if (pNumHead)
+ {
+ // Flush last non-NaN segment to the matrix.
+ rMat.PutDouble(pNumHead, pNum - pNumHead, nCol, pNumHead - pNums);
+ }
+}
+
+void flushStrSegment(
+ ScMatrix& rMat, size_t nCol, rtl_uString** pHead, rtl_uString** pCur, rtl_uString** pTop )
+{
+ size_t nOffset = pHead - pTop;
+ std::vector<svl::SharedString> aStrs;
+ aStrs.reserve(pCur - pHead);
+ for (; pHead != pCur; ++pHead)
+ aStrs.push_back(svl::SharedString(*pHead, *pHead));
+
+ rMat.PutString(&aStrs[0], aStrs.size(), nCol, nOffset);
+}
+
+void fillMatrix( ScMatrix& rMat, size_t nCol, rtl_uString** pStrs, size_t nLen )
+{
+ rtl_uString** p = pStrs;
+ rtl_uString** pEnd = p + nLen;
+ rtl_uString** pHead = nullptr;
+ for (; p != pEnd; ++p)
+ {
+ if (*p)
+ {
+ if (!pHead)
+ // Store the first non-empty string position.
+ pHead = p;
+
+ continue;
+ }
+
+ if (pHead)
+ {
+ // Flush this non-empty segment to the matrix.
+ flushStrSegment(rMat, nCol, pHead, p, pStrs);
+ pHead = nullptr;
+ }
+ }
+
+ if (pHead)
+ {
+ // Flush last non-empty segment to the matrix.
+ flushStrSegment(rMat, nCol, pHead, p, pStrs);
+ }
+}
+
+void fillMatrix( ScMatrix& rMat, size_t nCol, const double* pNums, rtl_uString** pStrs, size_t nLen )
+{
+ if (!pStrs)
+ {
+ fillMatrix(rMat, nCol, pNums, nLen);
+ return;
+ }
+
+ const double* pNum = pNums;
+ const double* pNumHead = nullptr;
+ rtl_uString** pStr = pStrs;
+ rtl_uString** pStrEnd = pStr + nLen;
+ rtl_uString** pStrHead = nullptr;
+
+ for (; pStr != pStrEnd; ++pStr, ++pNum)
+ {
+ if (*pStr)
+ {
+ // String cell exists.
+
+ if (pNumHead)
+ {
+ // Flush this numeric segment to the matrix.
+ rMat.PutDouble(pNumHead, pNum - pNumHead, nCol, pNumHead - pNums);
+ pNumHead = nullptr;
+ }
+
+ if (!pStrHead)
+ // Store the first non-empty string position.
+ pStrHead = pStr;
+
+ continue;
+ }
+
+ // No string cell. Check the numeric cell value.
+
+ if (pStrHead)
+ {
+ // Flush this non-empty string segment to the matrix.
+ flushStrSegment(rMat, nCol, pStrHead, pStr, pStrs);
+ pStrHead = nullptr;
+ }
+
+ if (!rtl::math::isNan(*pNum))
+ {
+ // Numeric cell exists.
+ if (!pNumHead)
+ // Store the first non-NaN position.
+ pNumHead = pNum;
+
+ continue;
+ }
+
+ // Empty cell. No action required.
+ }
+
+ if (pStrHead)
+ {
+ // Flush the last non-empty segment to the matrix.
+ flushStrSegment(rMat, nCol, pStrHead, pStr, pStrs);
+ }
+ else if (pNumHead)
+ {
+ // Flush the last numeric segment to the matrix.
+ rMat.PutDouble(pNumHead, pNum - pNumHead, nCol, pNumHead - pNums);
+ }
+}
+
+} // anonymous namespace
+
+void ScVectorRefMatrix::ensureFullMatrix()
+{
+ if (mpFullMatrix)
+ return;
+
+ const std::vector<formula::VectorRefArray>& rArrays = mpToken->GetArrays();
+ size_t nColSize = rArrays.size();
+ mpFullMatrix.reset(new ScFullMatrix(nColSize, mnRowSize));
+
+ for (size_t nCol = 0; nCol < nColSize; ++nCol)
+ {
+ const formula::VectorRefArray& rArray = rArrays[nCol];
+ if (rArray.mpStringArray)
+ {
+ if (rArray.mpNumericArray)
+ {
+ // Mixture of string and numeric values.
+ const double* pNums = rArray.mpNumericArray;
+ pNums += mnRowStart;
+ rtl_uString** pStrs = rArray.mpStringArray;
+ pStrs += mnRowStart;
+ fillMatrix(*mpFullMatrix, nCol, pNums, pStrs, mnRowSize);
+ }
+ else
+ {
+ // String cells only.
+ rtl_uString** pStrs = rArray.mpStringArray;
+ pStrs += mnRowStart;
+ fillMatrix(*mpFullMatrix, nCol, pStrs, mnRowSize);
+ }
+ }
+ else if (rArray.mpNumericArray)
+ {
+ // Numeric cells only.
+ const double* pNums = rArray.mpNumericArray;
+ pNums += mnRowStart;
+ fillMatrix(*mpFullMatrix, nCol, pNums, mnRowSize);
+ }
+ }
+}
+
ScVectorRefMatrix::ScVectorRefMatrix(const formula::DoubleVectorRefToken* pToken, SCSIZE nRowStart, SCSIZE nRowSize)
: ScMatrix()
, mpToken(pToken)
@@ -2853,282 +3041,350 @@ ScVectorRefMatrix::~ScVectorRefMatrix()
ScMatrix* ScVectorRefMatrix::Clone() const
{
- throw std::runtime_error("ScVectorRefMatrix::Clone() called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->Clone();
}
void ScVectorRefMatrix::Resize(SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::Resize called");
+ ensureFullMatrix();
+ mpFullMatrix->Resize(nC, nR);
}
void ScVectorRefMatrix::Resize(SCSIZE nC, SCSIZE nR, double fVal)
{
- throw std::runtime_error("ScVectorRefMatrix::Resize called");
+ ensureFullMatrix();
+ mpFullMatrix->Resize(nC, nR, fVal);
}
ScMatrix* ScVectorRefMatrix::CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const
{
- throw std::runtime_error("ScVectorRefMatrix::CloneAndExtend called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->CloneAndExtend(nNewCols, nNewRows);
}
void ScVectorRefMatrix::SetErrorInterpreter(ScInterpreter* p)
{
+ if (mpFullMatrix)
+ {
+ mpFullMatrix->SetErrorInterpreter(p);
+ return;
+ }
+
mpErrorInterpreter = p;
}
void ScVectorRefMatrix::GetDimensions(SCSIZE& rC, SCSIZE& rR) const
{
+ if (mpFullMatrix)
+ {
+ mpFullMatrix->GetDimensions(rC, rR);
+ return;
+ }
+
rC = mpToken->GetArrays().size();
rR = mnRowSize;
}
SCSIZE ScVectorRefMatrix::GetElementCount() const
{
- throw std::runtime_error("ScVectorRefMatrix::GetElementCount called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->GetElementCount();
}
bool ScVectorRefMatrix::ValidColRow(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::ValidColRow called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->ValidColRow(nC, nR);
}
bool ScVectorRefMatrix::ValidColRowReplicated(SCSIZE & rC, SCSIZE & rR) const
{
- throw std::runtime_error("ScVectorRefMatrix::ValidColRowReplicated called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->ValidColRowReplicated(rC, rR);
}
bool ScVectorRefMatrix::ValidColRowOrReplicated(SCSIZE & rC, SCSIZE & rR) const
{
- throw std::runtime_error("ScVectorRefMatrix::ValidColRowOrReplicated called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->ValidColRowOrReplicated(rC, rR);
}
void ScVectorRefMatrix::PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutDouble called");
+ ensureFullMatrix();
+ mpFullMatrix->PutDouble(fVal, nC, nR);
}
void ScVectorRefMatrix::PutDouble(double fVal, SCSIZE nIndex)
{
- throw std::runtime_error("ScVectorRefMatrix::PutDouble called");
+ ensureFullMatrix();
+ mpFullMatrix->PutDouble(fVal, nIndex);
}
void ScVectorRefMatrix::PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutDouble called");
+ ensureFullMatrix();
+ mpFullMatrix->PutDouble(pArray, nLen, nC, nR);
}
void ScVectorRefMatrix::PutString(const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutString called");
+ ensureFullMatrix();
+ mpFullMatrix->PutString(rStr, nC, nR);
}
void ScVectorRefMatrix::PutString(const svl::SharedString& rStr, SCSIZE nIndex)
{
- throw std::runtime_error("ScVectorRefMatrix::PutString called");
+ ensureFullMatrix();
+ mpFullMatrix->PutString(rStr, nIndex);
}
void ScVectorRefMatrix::PutString(const svl::SharedString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutString called");
+ ensureFullMatrix();
+ mpFullMatrix->PutString(pArray, nLen, nC, nR);
}
void ScVectorRefMatrix::PutEmpty(SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutEmpty called");
+ ensureFullMatrix();
+ mpFullMatrix->PutEmpty(nC, nR);
}
void ScVectorRefMatrix::PutEmptyPath(SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutEmptyPath called");
+ ensureFullMatrix();
+ mpFullMatrix->PutEmptyPath(nC, nR);
}
void ScVectorRefMatrix::PutError(sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutError called");
+ ensureFullMatrix();
+ mpFullMatrix->PutError(nErrorCode, nC, nR);
}
void ScVectorRefMatrix::PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutBoolean called");
+ ensureFullMatrix();
+ mpFullMatrix->PutBoolean(bVal, nC, nR);
}
void ScVectorRefMatrix::FillDouble(double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2)
{
- throw std::runtime_error("ScVectorRefMatrix::FillDouble called");
+ ensureFullMatrix();
+ mpFullMatrix->FillDouble(fVal, nC1, nR1, nC2, nR2);
}
void ScVectorRefMatrix::PutDoubleVector(const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutDoubleVector called");
+ ensureFullMatrix();
+ mpFullMatrix->PutDoubleVector(rVec, nC, nR);
}
void ScVectorRefMatrix::PutStringVector(const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutStringVector called");
+ ensureFullMatrix();
+ mpFullMatrix->PutStringVector(rVec, nC, nR);
}
void ScVectorRefMatrix::PutEmptyVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutEmptyVector called");
+ ensureFullMatrix();
+ mpFullMatrix->PutEmptyVector(nCount, nC, nR);
}
void ScVectorRefMatrix::PutEmptyResultVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutEmptyResultVector called");
+ ensureFullMatrix();
+ mpFullMatrix->PutEmptyResultVector(nCount, nC, nR);
}
void ScVectorRefMatrix::PutEmptyPathVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
{
- throw std::runtime_error("ScVectorRefMatrix::PutEmptyPathVector called");
+ ensureFullMatrix();
+ mpFullMatrix->PutEmptyPathVector(nCount, nC, nR);
}
sal_uInt16 ScVectorRefMatrix::GetError(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::GetError called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->GetError(nC, nR);
}
double ScVectorRefMatrix::GetDouble(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::GetDouble called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->GetDouble(nC, nR);
}
double ScVectorRefMatrix::GetDouble(SCSIZE nIndex) const
{
- throw std::runtime_error("ScVectorRefMatrix::GetDouble called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->GetDouble(nIndex);
}
svl::SharedString ScVectorRefMatrix::GetString(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::GetString called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->GetString(nC, nR);
}
svl::SharedString ScVectorRefMatrix::GetString(SCSIZE nIndex) const
{
- throw std::runtime_error("ScVectorRefMatrix::GetString called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->GetString(nIndex);
}
svl::SharedString ScVectorRefMatrix::GetString(SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::GetString called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->GetString(rFormatter, nC, nR);
}
ScMatrixValue ScVectorRefMatrix::Get(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::Get called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->Get(nC, nR);
}
bool ScVectorRefMatrix::IsString(SCSIZE nIndex) const
{
- throw std::runtime_error("ScVectorRefMatrix::IsString called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->IsString(nIndex);
}
bool ScVectorRefMatrix::IsString(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::IsString called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->IsString(nC, nR);
}
bool ScVectorRefMatrix::IsEmpty(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::IsEmpty called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->IsEmpty(nC, nR);
}
bool ScVectorRefMatrix::IsEmptyCell(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::IsEmptyCell called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->IsEmptyCell(nC, nR);
}
bool ScVectorRefMatrix::IsEmptyResult(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::IsEmptyResult called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->IsEmptyResult(nC, nR);
}
bool ScVectorRefMatrix::IsEmptyPath(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::IsEmptyPath called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->IsEmptyPath(nC, nR);
}
bool ScVectorRefMatrix::IsValue(SCSIZE nIndex) const
{
- throw std::runtime_error("ScVectorRefMatrix::IsValue called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->IsValue(nIndex);
}
bool ScVectorRefMatrix::IsValue(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::IsValue called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->IsValue(nC, nR);
}
bool ScVectorRefMatrix::IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::IsValueOrEmpty called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->IsValueOrEmpty(nC, nR);
}
bool ScVectorRefMatrix::IsBoolean(SCSIZE nC, SCSIZE nR) const
{
- throw std::runtime_error("ScVectorRefMatrix::IsBoolean called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->IsBoolean(nC, nR);
}
bool ScVectorRefMatrix::IsNumeric() const
{
- throw std::runtime_error("ScVectorRefMatrix::IsNumeric called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->IsNumeric();
}
void ScVectorRefMatrix::MatTrans(ScMatrix& mRes) const
{
- throw std::runtime_error("ScVectorRefMatrix::MatTrans called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ mpFullMatrix->MatTrans(mRes);
}
void ScVectorRefMatrix::MatCopy(ScMatrix& mRes) const
{
- throw std::runtime_error("ScVectorRefMatrix::MatCopy called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ mpFullMatrix->MatCopy(mRes);
}
void ScVectorRefMatrix::CompareEqual()
{
- throw std::runtime_error("ScVectorRefMatrix::CompareEqual called");
+ ensureFullMatrix();
+ mpFullMatrix->CompareEqual();
}
void ScVectorRefMatrix::CompareNotEqual()
{
- throw std::runtime_error("ScVectorRefMatrix::CompareNotEqual called");
+ ensureFullMatrix();
+ mpFullMatrix->CompareNotEqual();
}
void ScVectorRefMatrix::CompareLess()
{
- throw std::runtime_error("ScVectorRefMatrix::CompareLess called");
+ ensureFullMatrix();
+ mpFullMatrix->CompareLess();
}
void ScVectorRefMatrix::CompareGreater()
{
- throw std::runtime_error("ScVectorRefMatrix::CompareGreater called");
+ ensureFullMatrix();
+ mpFullMatrix->CompareGreater();
}
void ScVectorRefMatrix::CompareLessEqual()
{
- throw std::runtime_error("ScVectorRefMatrix::CompareLessEqual called");
+ ensureFullMatrix();
+ mpFullMatrix->CompareLessEqual();
}
void ScVectorRefMatrix::CompareGreaterEqual()
{
- throw std::runtime_error("ScVectorRefMatrix::CompareGreaterEqual called");
+ ensureFullMatrix();
+ mpFullMatrix->CompareGreaterEqual();
}
double ScVectorRefMatrix::And() const
{
- throw std::runtime_error("ScVectorRefMatrix::And called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->And();
}
double ScVectorRefMatrix::Or() const
{
- throw std::runtime_error("ScVectorRefMatrix::Or called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->Or();
}
double ScVectorRefMatrix::Xor() const
{
- throw std::runtime_error("ScVectorRefMatrix::Xor called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->Xor();
}
ScMatrix::IterateResult ScVectorRefMatrix::Sum(bool bTextAsZero) const
{
+ if (mpFullMatrix)
+ return mpFullMatrix->Sum(bTextAsZero);
+
const std::vector<formula::VectorRefArray>& rArrays = mpToken->GetArrays();
size_t nDataSize = mnRowSize;
@@ -3147,7 +3403,9 @@ ScMatrix::IterateResult ScVectorRefMatrix::Sum(bool bTextAsZero) const
{
if (rArray.mpStringArray)
{
- throw std::runtime_error("ScVectorRefMatrix::Sum - string array");
+ // FIXME operate directly on the array too
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->Sum(bTextAsZero);
}
else if (rArray.mpNumericArray)
{
@@ -3182,177 +3440,110 @@ ScMatrix::IterateResult ScVectorRefMatrix::Sum(bool bTextAsZero) const
ScMatrix::IterateResult ScVectorRefMatrix::SumSquare(bool bTextAsZero) const
{
- throw std::runtime_error("ScVectorRefMatrix::SumSquare called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->SumSquare(bTextAsZero);
}
ScMatrix::IterateResult ScVectorRefMatrix::Product(bool bTextAsZero) const
{
- throw std::runtime_error("ScVectorRefMatrix::Product called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->Product(bTextAsZero);
}
size_t ScVectorRefMatrix::Count(bool bCountStrings) const
{
- throw std::runtime_error("ScVectorRefMatrix::Count called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->Count(bCountStrings);
}
size_t ScVectorRefMatrix::MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const
{
- throw std::runtime_error("ScVectorRefMatrix::MatchDoubleInColumns called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->MatchDoubleInColumns(fValue, nCol1, nCol2);
}
size_t ScVectorRefMatrix::MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const
{
- throw std::runtime_error("ScVectorRefMatrix::MatchStringInColumns called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->MatchStringInColumns(rStr, nCol1, nCol2);
}
double ScVectorRefMatrix::GetMaxValue(bool bTextAsZero) const
{
- throw std::runtime_error("ScVectorRefMatrix::GetMaxValue called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->GetMaxValue(bTextAsZero);
}
double ScVectorRefMatrix::GetMinValue(bool bTextAsZero) const
{
- throw std::runtime_error("ScVectorRefMatrix::GetMinValue called");
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->GetMinValue(bTextAsZero);
}
ScMatrixRef ScVectorRefMatrix::CompareMatrix(sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions) const
{
- throw std::runtime_error("ScVectorRefMatrix::CompareMatrix called");
-#if 0
- // TODO FIXME
- return ScMatrixRef(new ScFullMatrix(mpToken->GetArrays().size(), mnRowSize));
-#endif
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ return mpFullMatrix->CompareMatrix(rComp, nMatPos, pOptions);
}
void ScVectorRefMatrix::GetDoubleArray(std::vector<double>& rVector, bool bEmptyAsZero) const
{
- throw std::runtime_error("ScVectorRefMatrix::GetDoubleArray called");
-#if 0
- const std::vector<formula::VectorRefArray>& rArrays = mpToken->GetArrays();
- size_t nDataSize = mnRowSize;
-
- if (mnRowStart >= mpToken->GetRefRowSize())
- {
- return;
- }
- else if (nDataSize > mpToken->GetRefRowSize() + mnRowStart)
- {
- nDataSize = mpToken->GetRefRowSize() - mnRowStart;
- }
-
- rVector.resize(rArrays.size()*nDataSize);
- std::vector<double>::iterator it = rVector.begin();
-
- for (const formula::VectorRefArray& rArray : rArrays)
- {
- if (rArray.mpStringArray)
- {
- // TODO FIXME
- std::fill(rVector.begin(), rVector.end(), 0.0);
- //throw std::runtime_error("ScVectorRefMatrix::GetDoubleArray - string array");
- }
- else if (rArray.mpNumericArray)
- {
- // Numeric cells only.
- const double* p = rArray.mpNumericArray + mnRowStart;
-
- // append to the array
- rVector.insert(rVector.end(), p, p + nDataSize);
- }
- }
-#endif
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ mpFullMatrix->GetDoubleArray(rVector, bEmptyAsZero);
}
void ScVectorRefMatrix::MergeDoubleArray(std::vector<double>& rVector, Op eOp) const
{
- throw std::runtime_error("ScVectorRefMatrix::MergeDoubleArray called");
-#if 0
- if (mnRowSize*mpToken->GetArrays().size() != rVector.size())
- return;
-
- const std::vector<formula::VectorRefArray>& rArrays = mpToken->GetArrays();
- size_t nDataSize = mnRowSize;
-
- if (mnRowStart >= mpToken->GetRefRowSize())
- {
- return;
- }
- else if (nDataSize > mpToken->GetRefRowSize() + mnRowStart)
- {
- nDataSize = mpToken->GetRefRowSize() - mnRowStart;
- }
-
- std::vector<double>::iterator it = rVector.begin();
-
- switch (eOp)
- {
- case ScFullMatrix::Mul:
- {
- for (const formula::VectorRefArray& rArray : rArrays)
- {
- if (rArray.mpStringArray)
- {
- throw std::runtime_error("ScVectorRefMatrix::MergeDoubleArray - string array");
- }
- else if (rArray.mpNumericArray)
- {
- // Numeric cells only.
- const double* p = rArray.mpNumericArray + mnRowStart;
-
- for (size_t nSize = nDataSize; nSize > 0; --nSize)
- {
- *it *= (*p);
- ++it;
- ++p;
- }
- }
- }
- }
- break;
- default:
- ;
- }
-#endif
+ const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+ mpFullMatrix->MergeDoubleArray(rVector, eOp);
}
void ScVectorRefMatrix::NotOp(ScMatrix& rMat)
{
- throw std::runtime_error("ScVectorRefMatrix::NotOp called");
+ ensureFullMatrix();
+ mpFullMatrix->NotOp(rMat);
}
void ScVectorRefMatrix::NegOp(ScMatrix& rMat)
{
- throw std::runtime_error("ScVectorRefMatrix::NegOp called");
+ ensureFullMatrix();
+ mpFullMatrix->NegOp(rMat);
}
void ScVectorRefMatrix::AddOp(double fVal, ScMatrix& rMat)
{
- throw std::runtime_error("ScVectorRefMatrix::AddOp called");
+ ensureFullMatrix();
+ mpFullMatrix->AddOp(fVal, rMat);
}
void ScVectorRefMatrix::SubOp(bool bFlag, double fVal, ScMatrix& rMat)
{
- throw std::runtime_error("ScVectorRefMatrix::SubOp called");
+ ensureFullMatrix();
+ mpFullMatrix->SubOp(bFlag, fVal, rMat);
}
void ScVectorRefMatrix::MulOp(double fVal, ScMatrix& rMat)
{
- throw std::runtime_error("ScVectorRefMatrix::MulOp called");
+ ensureFullMatrix();
+ mpFullMatrix->MulOp(fVal, rMat);
}
void ScVectorRefMatrix::DivOp(bool bFlag, double fVal, ScMatrix& rMat)
{
- throw std::runtime_error("ScVectorRefMatrix::DivOp called");
+ ensureFullMatrix();
+ mpFullMatrix->DivOp(bFlag, fVal, rMat);
}
void ScVectorRefMatrix::PowOp(bool bFlag, double fVal, ScMatrix& rMat)
{
- throw std::runtime_error("ScVectorRefMatrix::PowOp called");
+ ensureFullMatrix();
+ mpFullMatrix->PowOp(bFlag, fVal, rMat);
}
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");
+ ensureFullMatrix();
+ return mpFullMatrix->Collect(bTextAsZero, aOp);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index e97ef65..39fd0db 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -32,6 +32,7 @@
#include "compiler.hxx"
#include "interpre.hxx"
#include <formula/compiler.hrc>
+#include <formulagroup.hxx>
#include "rechead.hxx"
#include "parclass.hxx"
#include "jumpmatrix.hxx"
@@ -1321,7 +1322,9 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
return;
}
- if (!ScCalcConfig::isOpenCLEnabled() && ScInterpreter::GetGlobalConfig().mpSwInterpreterSubsetOpCodes->find(eOp) == ScInterpreter::GetGlobalConfig().mpSwInterpreterSubsetOpCodes->end())
+ // test for OpenCL interpreter first - the assumption is that S/W
+ // interpreter blacklist is more strict than the OpenCL one
+ if (ScCalcConfig::isSwInterpreterEnabled() && (dynamic_cast<sc::FormulaGroupInterpreterSoftware*>(sc::FormulaGroupInterpreter::getStatic()) != nullptr) && ScInterpreter::GetGlobalConfig().mpSwInterpreterSubsetOpCodes->find(eOp) == ScInterpreter::GetGlobalConfig().mpSwInterpreterSubsetOpCodes->end())
{
meVectorState = FormulaVectorDisabled;
return;
@@ -1568,9 +1571,12 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
return;
}
+ // only when openCL interpreter is not enabled - the assumption is that
+ // the S/W interpreter blacklist is more strict
if (eOp >= SC_OPCODE_START_BIN_OP &&
eOp <= SC_OPCODE_STOP_UN_OP &&
- !ScCalcConfig::isOpenCLEnabled() &&
+ ScCalcConfig::isSwInterpreterEnabled() &&
+ (dynamic_cast<sc::FormulaGroupInterpreterSoftware*>(sc::FormulaGroupInterpreter::getStatic()) != nullptr) &&
ScInterpreter::GetGlobalConfig().mpSwInterpreterSubsetOpCodes->find(eOp) == ScInterpreter::GetGlobalConfig().mpSwInterpreterSubsetOpCodes->end())
{
meVectorState = FormulaVectorDisabled;
More information about the Libreoffice-commits
mailing list