summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-04-30 11:16:21 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-04-30 13:10:45 -0400
commitc9aa06260000a3640a5557c2d34be7e2a82d8f91 (patch)
treebbc8f9668d5adf923c5231ef7026c3457be49f3e /sc
parent29bf5fa50d7471d4ea6d5d59c2e2b091000fd306 (diff)
Move the group calculation code into its own class.
To isolate the code that will be re-written for true vectorized calculation... Change-Id: I3ccd15841ed6fcdc6a22a590ba82d46d0b4863c5
Diffstat (limited to 'sc')
-rw-r--r--sc/Library_sc.mk1
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/inc/formulacell.hxx4
-rw-r--r--sc/inc/formulagroup.hxx22
-rw-r--r--sc/inc/types.hxx3
-rw-r--r--sc/source/core/data/column2.cxx1
-rw-r--r--sc/source/core/data/formulacell.cxx77
-rw-r--r--sc/source/core/tool/formulagroup.cxx96
8 files changed, 130 insertions, 76 deletions
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index fe5b4b154665..f7be65cc91e3 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -190,6 +190,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/tool/doubleref \
sc/source/core/tool/editutil \
sc/source/core/tool/filtopt \
+ sc/source/core/tool/formulagroup \
sc/source/core/tool/formulaopt \
sc/source/core/tool/formulaparserpool \
sc/source/core/tool/formularesult \
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index e70f108e70f2..e0773aab3e1b 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -82,8 +82,6 @@ struct ScFormulaCellGroup;
struct ScRefCellValue;
class ScDocumentImport;
-typedef ::boost::intrusive_ptr<ScFormulaCellGroup> ScFormulaCellGroupRef;
-
struct ScNeededSizeOptions
{
const ScPatternAttr* pPattern;
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index e4f1cfa5fd0e..2a8546f28a2f 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -51,8 +51,6 @@ inline void intrusive_ptr_release(ScFormulaCellGroup *p)
delete p;
}
-typedef ::boost::intrusive_ptr<ScFormulaCellGroup> ScFormulaCellGroupRef;
-
enum ScMatrixMode {
MM_NONE = 0, // No matrix formula
MM_FORMULA = 1, // Upper left matrix formula cell
@@ -282,6 +280,8 @@ public:
*/
void SetResultDouble( double n ) { aResult.SetDouble( n); }
+ void SetResultToken( const formula::FormulaToken* pToken );
+
double GetResultDouble() const { return aResult.GetDouble(); }
void SetErrCode( sal_uInt16 n );
diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index 0a8e3f7aa7c1..55f6e0997ff8 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -10,9 +10,15 @@
#ifndef SC_FORMULAGROUP_HXX
#define SC_FORMULAGROUP_HXX
+#include "address.hxx"
+#include "types.hxx"
+
#include <boost/noncopyable.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
+class ScDocument;
+class ScTokenArray;
+
namespace sc {
struct FormulaGroupContext : boost::noncopyable
@@ -23,6 +29,22 @@ struct FormulaGroupContext : boost::noncopyable
ArrayStoreType maArrays;
};
+/**
+ * All the vectorized formula calculation code should be collectd here.
+ */
+class FormulaGroupInterpreter
+{
+ ScDocument& mrDoc;
+ ScAddress maTopPos;
+ ScFormulaCellGroupRef mxGroup;
+ ScTokenArray& mrCode;
+public:
+ FormulaGroupInterpreter(
+ ScDocument& rDoc, const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode);
+
+ bool interpret();
+};
+
}
#endif
diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx
index 1af6e2d73b62..9654271c4887 100644
--- a/sc/inc/types.hxx
+++ b/sc/inc/types.hxx
@@ -20,6 +20,9 @@ typedef ::boost::intrusive_ptr<const ScMatrix> ScConstMatrixRef;
class ScToken;
typedef ::boost::intrusive_ptr<ScToken> ScTokenRef;
+struct ScFormulaCellGroup;
+typedef ::boost::intrusive_ptr<ScFormulaCellGroup> ScFormulaCellGroupRef;
+
/**
* When vectorization is enabled, we could potentially mass-calculate a
* series of formula token arrays in adjacent formula cells in one step,
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 2e20d0f1d53a..c93e043550a4 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1665,7 +1665,6 @@ bool ScColumn::ResolveStaticReference( ScMatrix& rMat, SCCOL nMatCol, SCROW nRow
const double* ScColumn::FetchDoubleArray( sc::FormulaGroupContext& /*rCxt*/, SCROW nRow1, SCROW nRow2 ) const
{
// TODO: I'll use the context object later.
-
if (nRow1 > nRow2)
return NULL;
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 3e85a9eeed2a..d271edc641b4 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1611,6 +1611,10 @@ bool ScFormulaCell::IsDirtyOrInTableOpDirty() const
return bDirty || (bTableOpDirty && pDocument->IsInInterpreterTableOp());
}
+void ScFormulaCell::SetResultToken( const formula::FormulaToken* pToken )
+{
+ aResult.SetToken(pToken);
+}
void ScFormulaCell::SetErrCode( sal_uInt16 n )
{
@@ -3071,77 +3075,8 @@ bool ScFormulaCell::InterpretFormulaGroup()
}
}
-#if 0
- // TODO: Calculate the formula group via vectorization.
-#else
- // Until we implement group calculation for real, decompose the group into
- // individual formula token arrays for individual calculation.
- ScAddress aTmpPos = aPos;
- for (sal_Int32 i = 0; i < xGroup->mnLength; ++i)
- {
- aTmpPos.SetRow(xGroup->mnStart + i);
- ScTokenArray aCode2;
- for (const formula::FormulaToken* p = aCode.First(); p; p = aCode.Next())
- {
- switch (p->GetType())
- {
- case svSingleVectorRef:
- {
- const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p);
- const double* pArray = p2->GetArray();
- aCode2.AddDouble(i < p2->GetArrayLength() ? pArray[i] : 0.0);
- }
- break;
- case svDoubleVectorRef:
- {
- const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p);
- const std::vector<const double*>& rArrays = p2->GetArrays();
- size_t nColSize = rArrays.size();
- size_t nRowStart = p2->IsStartFixed() ? 0 : i;
- size_t nRowEnd = p2->GetRefRowSize() - 1;
- if (!p2->IsEndFixed())
- nRowEnd += i;
-
- size_t nRowSize = nRowEnd - nRowStart + 1;
- ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0));
- for (size_t nCol = 0; nCol < nColSize; ++nCol)
- {
- const double* pArray = rArrays[nCol];
- for (size_t nRow = 0; nRow < nRowSize; ++nRow)
- {
- if (nRowStart + nRow < p2->GetArrayLength())
- {
- double fVal = pArray[nRowStart+nRow];
- pMat->PutDouble(fVal, nCol, nRow);
- }
- }
- }
-
- ScMatrixToken aTok(pMat);
- aCode2.AddToken(aTok);
- }
- break;
- default:
- aCode2.AddToken(*p);
- }
- }
-
- ScFormulaCell* pDest = pDocument->GetFormulaCell(aTmpPos);
- if (!pDest)
- return false;
-
- ScCompiler aComp(pDocument, aPos, aCode2);
- aComp.SetGrammar(pDocument->GetGrammar());
- aComp.CompileTokenArray(); // Create RPN token array.
- ScInterpreter aInterpreter(pDest, pDocument, aTmpPos, aCode2);
- aInterpreter.Interpret();
-
- pDest->aResult.SetToken(aInterpreter.GetResultToken().get());
- pDest->ResetDirty();
- }
-
- return true;
-#endif
+ sc::FormulaGroupInterpreter aInterpreter(*pDocument, aPos, xGroup, aCode);
+ return aInterpreter.interpret();
}
bool ScFormulaCell::InterpretInvariantFormulaGroup()
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
new file mode 100644
index 000000000000..9f76fe2d052a
--- /dev/null
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "formulagroup.hxx"
+#include "document.hxx"
+#include "formulacell.hxx"
+#include "tokenarray.hxx"
+#include "compiler.hxx"
+#include "interpre.hxx"
+
+#include "formula/vectortoken.hxx"
+
+namespace sc {
+
+FormulaGroupInterpreter::FormulaGroupInterpreter(
+ ScDocument& rDoc, const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) :
+ mrDoc(rDoc), maTopPos(rTopPos), mxGroup(xGroup), mrCode(rCode) {}
+
+bool FormulaGroupInterpreter::interpret()
+{
+ // Until we implement group calculation for real, decompose the group into
+ // individual formula token arrays for individual calculation.
+ ScAddress aTmpPos = maTopPos;
+ for (sal_Int32 i = 0; i < mxGroup->mnLength; ++i)
+ {
+ aTmpPos.SetRow(mxGroup->mnStart + i);
+ ScTokenArray aCode2;
+ for (const formula::FormulaToken* p = mrCode.First(); p; p = mrCode.Next())
+ {
+ switch (p->GetType())
+ {
+ case formula::svSingleVectorRef:
+ {
+ const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p);
+ const double* pArray = p2->GetArray();
+ aCode2.AddDouble(i < p2->GetArrayLength() ? pArray[i] : 0.0);
+ }
+ break;
+ case formula::svDoubleVectorRef:
+ {
+ const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p);
+ const std::vector<const double*>& rArrays = p2->GetArrays();
+ size_t nColSize = rArrays.size();
+ size_t nRowStart = p2->IsStartFixed() ? 0 : i;
+ size_t nRowEnd = p2->GetRefRowSize() - 1;
+ if (!p2->IsEndFixed())
+ nRowEnd += i;
+
+ size_t nRowSize = nRowEnd - nRowStart + 1;
+ ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0));
+ for (size_t nCol = 0; nCol < nColSize; ++nCol)
+ {
+ const double* pArray = rArrays[nCol];
+ for (size_t nRow = 0; nRow < nRowSize; ++nRow)
+ {
+ if (nRowStart + nRow < p2->GetArrayLength())
+ {
+ double fVal = pArray[nRowStart+nRow];
+ pMat->PutDouble(fVal, nCol, nRow);
+ }
+ }
+ }
+
+ ScMatrixToken aTok(pMat);
+ aCode2.AddToken(aTok);
+ }
+ break;
+ default:
+ aCode2.AddToken(*p);
+ }
+ }
+
+ ScFormulaCell* pDest = mrDoc.GetFormulaCell(aTmpPos);
+ if (!pDest)
+ return false;
+
+ ScCompiler aComp(&mrDoc, aTmpPos, aCode2);
+ aComp.SetGrammar(mrDoc.GetGrammar());
+ aComp.CompileTokenArray(); // Create RPN token array.
+ ScInterpreter aInterpreter(pDest, &mrDoc, aTmpPos, aCode2);
+ aInterpreter.Interpret();
+
+ pDest->SetResultToken(aInterpreter.GetResultToken().get());
+ pDest->ResetDirty();
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */