[Libreoffice-commits] .: Branch 'feature/matrix-new-backend' - 4 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Tue Jul 17 09:05:11 PDT 2012


 sc/inc/scmatrix.hxx                         |   15 
 sc/qa/unit/ucalc.cxx                        |  111 ++--
 sc/source/core/data/validat.cxx             |    2 
 sc/source/core/inc/jumpmatrix.hxx           |    2 
 sc/source/core/tool/addincol.cxx            |    6 
 sc/source/core/tool/ddelink.cxx             |    2 
 sc/source/core/tool/interpr1.cxx            |    8 
 sc/source/core/tool/interpr5.cxx            |    7 
 sc/source/core/tool/rangeseq.cxx            |    2 
 sc/source/core/tool/scmatrix.cxx            |  642 ++++++++++++++++++----------
 sc/source/core/tool/token.cxx               |    2 
 sc/source/filter/excel/xihelper.cxx         |    2 
 sc/source/filter/xml/XMLDDELinksContext.cxx |    2 
 sc/source/ui/docshell/externalrefmgr.cxx    |    9 
 14 files changed, 489 insertions(+), 323 deletions(-)

New commits:
commit a720be999d40f92be559038836785bc012af9b90
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jul 17 11:56:53 2012 -0400

    A little cleanup.
    
    Change-Id: Ib0059f921f815a0ddb679f4bc1888eec2270981e

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 4146d26..c667846 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -294,7 +294,6 @@ struct custom_string_trait
 namespace {
 
 typedef mdds::multi_type_matrix<custom_string_trait> MatrixImplType;
-//typedef ::mdds::mixed_type_matrix< ::rtl::OUString, sal_uInt8> MatrixImplType;
 
 struct ElemEqual : public unary_function<double, bool>
 {
@@ -368,25 +367,6 @@ void compareMatrix(MatrixImplType& rMat)
     }
 }
 
-#if 0
-/**
- * Return a numeric value from a matrix element no matter what its type is.
- */
-double getNumericValue(const MatrixImplType::element& elem)
-{
-    switch (elem.m_type)
-    {
-        case mdds::element_boolean:
-            return static_cast<double>(elem.m_boolean);
-        case mdds::element_numeric:
-            return elem.m_numeric;
-        default:
-            ;
-    }
-    return 0.0;
-}
-#endif
-
 }
 
 class ScMatrixImpl
commit 5641100674e9494162c19687604dfa826c714b97
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jul 17 11:54:35 2012 -0400

    Implement Sum(), SumSquare(), etc...
    
    The unit test still segfaults.
    
    Change-Id: Ib1fc78f94776e04ba8cb6ec8a24162b308cc569f

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index ee6e658..4146d26 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -975,24 +975,150 @@ double ScMatrixImpl::Or() const
     return EvalMatrix<OrEvaluator>(maMat);
 }
 
+namespace {
+
+struct SumOp
+{
+    void operator() (double& rAccum, double fVal)
+    {
+        rAccum += fVal;
+    }
+};
+
+struct SumSquareOp
+{
+    void operator() (double& rAccum, double fVal)
+    {
+        rAccum += fVal*fVal;
+    }
+};
+
+struct ProductOp
+{
+    void operator() (double& rAccum, double fVal)
+    {
+        rAccum *= fVal;
+    }
+};
+
+template<typename _Op>
+class WalkElementBlocks : std::unary_function<MatrixImplType::element_block_node_type, void>
+{
+    _Op maOp;
+
+    ScMatrix::IterateResult maRes;
+    bool mbFirst:1;
+    bool mbTextAsZero:1;
+public:
+    WalkElementBlocks(bool bTextAsZero) : maRes(0.0, 0.0, 0), mbFirst(true), mbTextAsZero(bTextAsZero) {}
+
+    const ScMatrix::IterateResult& getResult() const { return maRes; }
+
+    void operator() (const MatrixImplType::element_block_node_type& node)
+    {
+        switch (node.type)
+        {
+            case mdds::mtm::element_numeric:
+            {
+                mdds::mtv::numeric_element_block::const_iterator it = mdds::mtv::numeric_element_block::begin(*node.data);
+                mdds::mtv::numeric_element_block::const_iterator itEnd = mdds::mtv::numeric_element_block::end(*node.data);
+                for (; it != itEnd; ++it)
+                {
+                    if (mbFirst)
+                    {
+                        maOp(maRes.mfFirst, *it);
+                        mbFirst = false;
+                    }
+                    else
+                        maOp(maRes.mfRest, *it);
+                }
+                maRes.mnCount += node.size;
+            }
+            break;
+            case mdds::mtm::element_boolean:
+            {
+                mdds::mtv::boolean_element_block::const_iterator it = mdds::mtv::boolean_element_block::begin(*node.data);
+                mdds::mtv::boolean_element_block::const_iterator itEnd = mdds::mtv::boolean_element_block::end(*node.data);
+                for (; it != itEnd; ++it)
+                {
+                    if (mbFirst)
+                    {
+                        maOp(maRes.mfFirst, *it);
+                        mbFirst = false;
+                    }
+                    else
+                        maOp(maRes.mfRest, *it);
+                }
+                maRes.mnCount += node.size;
+            }
+            break;
+            case mdds::mtm::element_string:
+                if (mbTextAsZero)
+                    maRes.mnCount += node.size;
+            break;
+            case mdds::mtm::element_empty:
+            default:
+                ;
+        }
+    }
+};
+
+class CountElements : std::unary_function<MatrixImplType::element_block_node_type, void>
+{
+    size_t mnCount;
+    bool mbCountString;
+public:
+    CountElements(bool bCountString) : mnCount(0), mbCountString(bCountString) {}
+
+    size_t getCount() const { return mnCount; }
+
+    void operator() (const MatrixImplType::element_block_node_type& node)
+    {
+        switch (node.type)
+        {
+            case mdds::mtm::element_numeric:
+            case mdds::mtm::element_boolean:
+                mnCount += node.size;
+            break;
+            case mdds::mtm::element_string:
+                if (mbCountString)
+                    mnCount += node.size;
+            break;
+            case mdds::mtm::element_empty:
+            default:
+                ;
+        }
+    }
+};
+
+}
+
 ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const
 {
-    return ScMatrix::IterateResult(0, 0, 0);
+    WalkElementBlocks<SumOp> aFunc(bTextAsZero);
+    maMat.walk(aFunc);
+    return aFunc.getResult();
 }
 
 ScMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const
 {
-    return ScMatrix::IterateResult(0, 0, 0);
+    WalkElementBlocks<SumSquareOp> aFunc(bTextAsZero);
+    maMat.walk(aFunc);
+    return aFunc.getResult();
 }
 
 ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const
 {
-    return ScMatrix::IterateResult(0, 0, 0);
+    WalkElementBlocks<ProductOp> aFunc(bTextAsZero);
+    maMat.walk(aFunc);
+    return aFunc.getResult();
 }
 
 size_t ScMatrixImpl::Count(bool bCountStrings) const
 {
-    return 0;
+    CountElements aFunc(bCountStrings);
+    maMat.walk(aFunc);
+    return aFunc.getCount();
 }
 
 void ScMatrixImpl::CalcPosition(SCSIZE nIndex, SCSIZE& rC, SCSIZE& rR) const
commit 21b5b6e929d2f4cabb6f84a1d4eddbf4814aeb5a
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Mon Jul 16 23:24:40 2012 -0400

    Now, we need to explicitly pass 0.0 as the initial value of a matrix.
    
    The new matrix class allows arbitrary initial values instead of just
    0.0 or empty values.  With this, the caller now has to explicitly pass
    zero value to the constructor if it wants to create a matrix filled with
    zeros.
    
    Change-Id: Ie515358b512fdb83ae60f54ab4ab49c92ca5761d

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index b816f5c..2c1006c 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1227,72 +1227,57 @@ struct PartiallyFilledEmptyMatrix
 void Test::testMatrix()
 {
     ScMatrixRef pMat;
-    ScMatrix::DensityType eDT[2];
 
-    // First, test the zero matrix types.
-    eDT[0] = ScMatrix::FILLED_ZERO;
-    eDT[1] = ScMatrix::SPARSE_ZERO;
-    for (int i = 0; i < 2; ++i)
-    {
-        pMat = new ScMatrix(0, 0, eDT[i]);
-        SCSIZE nC, nR;
-        pMat->GetDimensions(nC, nR);
-        CPPUNIT_ASSERT_MESSAGE("matrix is not empty", nC == 0 && nR == 0);
-        pMat->Resize(4, 10);
-        pMat->GetDimensions(nC, nR);
-        CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 4 && nR == 10);
-        CPPUNIT_ASSERT_MESSAGE("both 'and' and 'or' should evaluate to false",
-                               !pMat->And() && !pMat->Or());
-
-        // Resizing into a larger matrix should fill the void space with zeros.
-        checkMatrixElements<AllZeroMatrix>(*pMat);
-
-        pMat->FillDouble(3.0, 1, 2, 2, 8);
-        checkMatrixElements<PartiallyFilledZeroMatrix>(*pMat);
-        CPPUNIT_ASSERT_MESSAGE("matrix is expected to be numeric", pMat->IsNumeric());
-        CPPUNIT_ASSERT_MESSAGE("partially non-zero matrix should evaluate false on 'and' and true on 'or",
-                               !pMat->And() && pMat->Or());
-        pMat->FillDouble(5.0, 0, 0, nC-1, nR-1);
-        CPPUNIT_ASSERT_MESSAGE("fully non-zero matrix should evaluate true both on 'and' and 'or",
-                               pMat->And() && pMat->Or());
-    }
+    // First, test the zero matrix type.
+    pMat = new ScMatrix(0, 0, 0.0);
+    SCSIZE nC, nR;
+    pMat->GetDimensions(nC, nR);
+    CPPUNIT_ASSERT_MESSAGE("matrix is not empty", nC == 0 && nR == 0);
+    pMat->Resize(4, 10);
+    pMat->GetDimensions(nC, nR);
+    CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 4 && nR == 10);
+    CPPUNIT_ASSERT_MESSAGE("both 'and' and 'or' should evaluate to false",
+                           !pMat->And() && !pMat->Or());
+
+    // Resizing into a larger matrix should fill the void space with zeros.
+    checkMatrixElements<AllZeroMatrix>(*pMat);
+
+    pMat->FillDouble(3.0, 1, 2, 2, 8);
+    checkMatrixElements<PartiallyFilledZeroMatrix>(*pMat);
+    CPPUNIT_ASSERT_MESSAGE("matrix is expected to be numeric", pMat->IsNumeric());
+    CPPUNIT_ASSERT_MESSAGE("partially non-zero matrix should evaluate false on 'and' and true on 'or",
+                           !pMat->And() && pMat->Or());
+    pMat->FillDouble(5.0, 0, 0, nC-1, nR-1);
+    CPPUNIT_ASSERT_MESSAGE("fully non-zero matrix should evaluate true both on 'and' and 'or",
+                           pMat->And() && pMat->Or());
 
     // Test the AND and OR evaluations.
-    for (int i = 0; i < 2; ++i)
-    {
-        pMat = new ScMatrix(2, 2, eDT[i]);
-
-        // Only some of the elements are non-zero.
-        pMat->PutBoolean(true, 0, 0);
-        pMat->PutDouble(1.0, 1, 1);
-        CPPUNIT_ASSERT_MESSAGE("incorrect OR result", pMat->Or());
-        CPPUNIT_ASSERT_MESSAGE("incorrect AND result", !pMat->And());
-
-        // All of the elements are non-zero.
-        pMat->PutBoolean(true, 0, 1);
-        pMat->PutDouble(2.3, 1, 0);
-        CPPUNIT_ASSERT_MESSAGE("incorrect OR result", pMat->Or());
-        CPPUNIT_ASSERT_MESSAGE("incorrect AND result", pMat->And());
-    }
-
-    // Now test the emtpy matrix types.
-    eDT[0] = ScMatrix::FILLED_EMPTY;
-    eDT[1] = ScMatrix::SPARSE_EMPTY;
-    for (int i = 0; i < 2; ++i)
-    {
-        pMat = new ScMatrix(10, 20, eDT[i]);
-        SCSIZE nC, nR;
-        pMat->GetDimensions(nC, nR);
-        CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 10 && nR == 20);
-        checkMatrixElements<AllEmptyMatrix>(*pMat);
-
-        pMat->PutBoolean(true, 1, 1);
-        pMat->PutDouble(-12.5, 4, 5);
-        rtl::OUString aStr("Test");
-        pMat->PutString(aStr, 8, 2);
-        pMat->PutEmptyPath(8, 11);
-        checkMatrixElements<PartiallyFilledEmptyMatrix>(*pMat);
-    }
+    pMat = new ScMatrix(2, 2, 0.0);
+
+    // Only some of the elements are non-zero.
+    pMat->PutBoolean(true, 0, 0);
+    pMat->PutDouble(1.0, 1, 1);
+    CPPUNIT_ASSERT_MESSAGE("incorrect OR result", pMat->Or());
+    CPPUNIT_ASSERT_MESSAGE("incorrect AND result", !pMat->And());
+
+    // All of the elements are non-zero.
+    pMat->PutBoolean(true, 0, 1);
+    pMat->PutDouble(2.3, 1, 0);
+    CPPUNIT_ASSERT_MESSAGE("incorrect OR result", pMat->Or());
+    CPPUNIT_ASSERT_MESSAGE("incorrect AND result", pMat->And());
+
+    // Now test the emtpy matrix type.
+    pMat = new ScMatrix(10, 20);
+    pMat->GetDimensions(nC, nR);
+    CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 10 && nR == 20);
+    checkMatrixElements<AllEmptyMatrix>(*pMat);
+
+    pMat->PutBoolean(true, 1, 1);
+    pMat->PutDouble(-12.5, 4, 5);
+    rtl::OUString aStr("Test");
+    pMat->PutString(aStr, 8, 2);
+    pMat->PutEmptyPath(8, 11);
+    checkMatrixElements<PartiallyFilledEmptyMatrix>(*pMat);
 }
 
 namespace {
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index 4ccb551..4dd8f2e 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -628,7 +628,7 @@ bool ScValidationData::GetSelectionFromFormula(
         // is stored as a single value.
 
         // Use an interim matrix to create the TypedStrData below.
-        xMatRef = new ScMatrix(1,1);
+        xMatRef = new ScMatrix(1, 1, 0.0);
 
         sal_uInt16 nErrCode = aValidationSrc.GetErrCode();
         if (nErrCode)
diff --git a/sc/source/core/tool/addincol.cxx b/sc/source/core/tool/addincol.cxx
index ba2c9cb..33c9232 100644
--- a/sc/source/core/tool/addincol.cxx
+++ b/sc/source/core/tool/addincol.cxx
@@ -1650,7 +1650,7 @@ void ScUnoAddInCall::SetResult( const uno::Any& rNewRes )
                     {
                         xMatrix = new ScMatrix(
                                 static_cast<SCSIZE>(nMaxColCount),
-                                static_cast<SCSIZE>(nRowCount) );
+                                static_cast<SCSIZE>(nRowCount), 0.0);
                         for (nRow=0; nRow<nRowCount; nRow++)
                         {
                             long nColCount = pRowArr[nRow].getLength();
@@ -1692,7 +1692,7 @@ void ScUnoAddInCall::SetResult( const uno::Any& rNewRes )
                     {
                         xMatrix = new ScMatrix(
                                 static_cast<SCSIZE>(nMaxColCount),
-                                static_cast<SCSIZE>(nRowCount) );
+                                static_cast<SCSIZE>(nRowCount), 0.0);
                         for (nRow=0; nRow<nRowCount; nRow++)
                         {
                             long nColCount = pRowArr[nRow].getLength();
@@ -1734,7 +1734,7 @@ void ScUnoAddInCall::SetResult( const uno::Any& rNewRes )
                     {
                         xMatrix = new ScMatrix(
                                 static_cast<SCSIZE>(nMaxColCount),
-                                static_cast<SCSIZE>(nRowCount) );
+                                static_cast<SCSIZE>(nRowCount), 0.0);
                         for (nRow=0; nRow<nRowCount; nRow++)
                         {
                             long nColCount = pRowArr[nRow].getLength();
diff --git a/sc/source/core/tool/ddelink.cxx b/sc/source/core/tool/ddelink.cxx
index 5bac102..aef6b49 100644
--- a/sc/source/core/tool/ddelink.cxx
+++ b/sc/source/core/tool/ddelink.cxx
@@ -166,7 +166,7 @@ sfx2::SvBaseLink::UpdateResult ScDdeLink::DataChanged(
     else                                // Daten aufteilen
     {
         //  Matrix immer neu anlegen, damit bIsString nicht durcheinanderkommt
-        pResult = new ScMatrix( nCols, nRows );
+        pResult = new ScMatrix(nCols, nRows, 0.0);
 
         SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
 
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 4b453b2..b10aea7 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5333,7 +5333,7 @@ void ScInterpreter::ScSumIf()
             break;
             case svExternalSingleRef:
             {
-                pSumExtraMatrix = new ScMatrix(1, 1);
+                pSumExtraMatrix = new ScMatrix(1, 1, 0.0);
                 ScExternalRefCache::TokenRef pToken;
                 PopExternalSingleRef(pToken);
                 if (!pToken)
@@ -5957,7 +5957,7 @@ void ScInterpreter::ScLookup()
         ScMatrixRef pDataMat2;
         if (bVertical)
         {
-            ScMatrixRef pTempMat(new ScMatrix(1, nR));
+            ScMatrixRef pTempMat(new ScMatrix(1, nR, 0.0));
             for (SCSIZE i = 0; i < nR; ++i)
                 if (pDataMat->IsValue(0, i))
                     pTempMat->PutDouble(pDataMat->GetDouble(0, i), 0, i);
@@ -5967,7 +5967,7 @@ void ScInterpreter::ScLookup()
         }
         else
         {
-            ScMatrixRef pTempMat(new ScMatrix(nC, 1));
+            ScMatrixRef pTempMat(new ScMatrix(nC, 1, 0.0));
             for (SCSIZE i = 0; i < nC; ++i)
                 if (pDataMat->IsValue(i, 0))
                     pTempMat->PutDouble(pDataMat->GetDouble(i, 0), i, 0);
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index eaa5a38..ba868bc 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -326,7 +326,7 @@ void ScInterpreter:: ScLCM()
 ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR)
 {
     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetNewMat" );
-    ScMatrixRef pMat = new ScMatrix( nC, nR);
+    ScMatrixRef pMat = new ScMatrix(nC, nR, 0.0);
     pMat->SetErrorInterpreter( this);
     // A temporary matrix is mutable and ScMatrix::CloneIfConst() returns the
     // very matrix.
@@ -556,18 +556,17 @@ ScMatrixRef ScInterpreter::GetMatrix()
             }
             if (pToken->GetType() == svDouble)
             {
-                pMat = new ScMatrix(1, 1);
+                pMat = new ScMatrix(1, 1, 0.0);
                 pMat->PutDouble(pToken->GetDouble(), 0, 0);
             }
             else if (pToken->GetType() == svString)
             {
-                pMat = new ScMatrix(1, 1);
+                pMat = new ScMatrix(1, 1, 0.0);
                 pMat->PutString(pToken->GetString(), 0, 0);
             }
             else
             {
                 pMat = new ScMatrix(1, 1);
-                pMat->PutEmpty(0, 0);
             }
         }
         break;
diff --git a/sc/source/core/tool/rangeseq.cxx b/sc/source/core/tool/rangeseq.cxx
index 9285051..ff35018 100644
--- a/sc/source/core/tool/rangeseq.cxx
+++ b/sc/source/core/tool/rangeseq.cxx
@@ -410,7 +410,7 @@ ScMatrixRef ScSequenceToMatrix::CreateMixedMatrix( const com::sun::star::uno::An
             rtl::OUString aUStr;
             xMatrix = new ScMatrix(
                     static_cast<SCSIZE>(nMaxColCount),
-                    static_cast<SCSIZE>(nRowCount) );
+                    static_cast<SCSIZE>(nRowCount), 0.0);
             SCSIZE nCols, nRows;
             xMatrix->GetDimensions( nCols, nRows);
             if (nCols != static_cast<SCSIZE>(nMaxColCount) || nRows != static_cast<SCSIZE>(nRowCount))
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 1d7f2a1..00e17c0 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1492,7 +1492,7 @@ FormulaToken* ScTokenArray::MergeArray( )
         return NULL;
 
     int nSign = 1;
-    ScMatrix* pArray = new ScMatrix( nCol, nRow );
+    ScMatrix* pArray = new ScMatrix(nCol, nRow, 0.0);
     for ( i = nStart, nCol = 0, nRow = 0 ; i < nLen ; i++ )
     {
         t = pCode[i];
diff --git a/sc/source/filter/excel/xihelper.cxx b/sc/source/filter/excel/xihelper.cxx
index 034a727..edac049 100644
--- a/sc/source/filter/excel/xihelper.cxx
+++ b/sc/source/filter/excel/xihelper.cxx
@@ -861,7 +861,7 @@ ScMatrixRef XclImpCachedMatrix::CreateScMatrix() const
     OSL_ENSURE( mnScCols * mnScRows == maValueList.size(), "XclImpCachedMatrix::CreateScMatrix - element count mismatch" );
     if( mnScCols && mnScRows && static_cast< sal_uLong >( mnScCols * mnScRows ) <= maValueList.size() )
     {
-        xScMatrix = new ScMatrix( mnScCols, mnScRows );
+        xScMatrix = new ScMatrix(mnScCols, mnScRows, 0.0);
         XclImpValueList::const_iterator itValue = maValueList.begin();
         for( SCSIZE nScRow = 0; nScRow < mnScRows; ++nScRow )
         {
diff --git a/sc/source/filter/xml/XMLDDELinksContext.cxx b/sc/source/filter/xml/XMLDDELinksContext.cxx
index 54eafd0..4c3c496 100644
--- a/sc/source/filter/xml/XMLDDELinksContext.cxx
+++ b/sc/source/filter/xml/XMLDDELinksContext.cxx
@@ -169,7 +169,7 @@ void ScXMLDDELinkContext::EndElement()
             OSL_ENSURE( static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size(),
                     "ScXMLDDELinkContext::EndElement: adapted matrix dimension doesn't match either");
         }
-        ScMatrixRef pMatrix = new ScMatrix( static_cast<SCSIZE>(nColumns), static_cast<SCSIZE>(nRows) );
+        ScMatrixRef pMatrix = new ScMatrix(static_cast<SCSIZE>(nColumns), static_cast<SCSIZE>(nRows), 0.0);
         sal_Int32 nCol(0);
         sal_Int32 nRow(-1);
         sal_Int32 nIndex(0);
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 101a8ac..e1e18c1 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -1465,9 +1465,6 @@ static ScTokenArray* lcl_fillEmptyMatrix(const ScRange& rRange)
     SCSIZE nC = static_cast<SCSIZE>(rRange.aEnd.Col()-rRange.aStart.Col()+1);
     SCSIZE nR = static_cast<SCSIZE>(rRange.aEnd.Row()-rRange.aStart.Row()+1);
     ScMatrixRef xMat = new ScMatrix(nC, nR);
-    for (SCSIZE i = 0; i < nC; ++i)
-        for (SCSIZE j = 0; j < nR; ++j)
-            xMat->PutEmpty(i, j);
 
     ScMatrixToken aToken(xMat);
     SAL_WNODEPRECATED_DECLARATIONS_PUSH
commit 207f8793e4d7c47eaf0281d5e21c7e90635b20df
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Mon Jul 16 23:05:50 2012 -0400

    Initial cut on matrix backend swapping. Still lots of things to fix.
    
    Change-Id: I5262899171029772f53dccc9aea666c4b83aef36

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 9657540..d6d3e15 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -169,12 +169,16 @@ public:
     /// The maximum number of elements a matrix may have at runtime.
     inline static size_t GetElementsMax()
     {
+        // TODO: Fix me.
+        return 0x08000000;
+#if 0
         // Roughly 125MB in total, divided by 8+1 per element => 14M elements.
         const size_t nMemMax = 0x08000000 / (sizeof(ScMatrixValue) + sizeof(ScMatValType));
         // With MAXROWCOUNT==65536 and 128 columns => 8M elements ~72MB.
         const size_t nArbitraryLimit = (size_t)MAXROWCOUNT * 128;
         // Stuffed with a million rows would limit this to 14 columns.
         return nMemMax < nArbitraryLimit ? nMemMax : nArbitraryLimit;
+#endif
     }
 
     /// Value or boolean.
@@ -215,11 +219,11 @@ public:
         return (nType & SC_MATVAL_NONVALUE) == SC_MATVAL_EMPTYPATH;
     }
 
-    ScMatrix( SCSIZE nC, SCSIZE nR, DensityType eType = FILLED_ZERO);
+    ScMatrix(SCSIZE nC, SCSIZE nR);
+    ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal);
 
     /** Clone the matrix. */
     ScMatrix* Clone() const;
-    ScMatrix* Clone( DensityType eType) const;
 
     /** Clone the matrix if mbCloneIfConst (immutable) is set, otherwise
         return _this_ matrix, to be assigned to a ScMatrixRef. */
@@ -236,7 +240,7 @@ public:
 
     /** Clone the matrix and extend it to the new size. nNewCols and nNewRows
         MUST be at least of the size of the original matrix. */
-    ScMatrix* CloneAndExtend( SCSIZE nNewCols, SCSIZE nNewRows, DensityType eType) const;
+    ScMatrix* CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const;
 
     inline void IncRef() const
     {
@@ -249,7 +253,6 @@ public:
             delete this;
     }
 
-    DensityType GetDensityType() const;
     void SetErrorInterpreter( ScInterpreter* p);
     void GetDimensions( SCSIZE& rC, SCSIZE& rR) const;
     SCSIZE GetElementCount() const;
@@ -303,9 +306,9 @@ public:
     double GetDouble( SCSIZE nIndex) const;
 
     /// @return empty string if empty or empty path, else string content.
-    const ::rtl::OUString& GetString( SCSIZE nC, SCSIZE nR) const;
+    rtl::OUString GetString( SCSIZE nC, SCSIZE nR) const;
     /// @return empty string if empty or empty path, else string content.
-    const ::rtl::OUString& GetString( SCSIZE nIndex) const;
+    rtl::OUString GetString( SCSIZE nIndex) const;
 
     /** @returns the matrix element's string if one is present, otherwise the
         numerical value formatted as string, or in case of an error the error
diff --git a/sc/source/core/inc/jumpmatrix.hxx b/sc/source/core/inc/jumpmatrix.hxx
index be2719c..27dfecd 100644
--- a/sc/source/core/inc/jumpmatrix.hxx
+++ b/sc/source/core/inc/jumpmatrix.hxx
@@ -195,7 +195,7 @@ public:
                                     {
                                         if ( nNewCols > nResMatCols || nNewRows > nResMatRows )
                                         {
-                                            pMat = pMat->CloneAndExtend( nNewCols, nNewRows, pMat->GetDensityType() );
+                                            pMat = pMat->CloneAndExtend(nNewCols, nNewRows);
                                             if ( nResMatCols < nNewCols )
                                             {
                                                 pMat->FillDouble( CreateDoubleError(
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 15c1c89..4b453b2 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -4621,7 +4621,7 @@ public:
         return mbColVec ? mrMat.GetDouble(0, i) : mrMat.GetDouble(i, 0);
     }
 
-    const rtl::OUString& GetString(SCSIZE i) const
+    rtl::OUString GetString(SCSIZE i) const
     {
         return mbColVec ? mrMat.GetString(0, i) : mrMat.GetString(i, 0);
     }
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 0aa891a..ee6e658 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -38,21 +38,263 @@
 
 #include <math.h>
 
-#define MDDS_HASH_CONTAINER_BOOST 1
-#include <mdds/mixed_type_matrix.hpp>
+#include <mdds/multi_type_matrix.hpp>
+#include <mdds/multi_type_vector_types.hpp>
+#include <mdds/multi_type_vector_trait.hpp>
 
 using ::std::pair;
 using ::std::for_each;
 using ::std::count_if;
 using ::std::advance;
 using ::std::unary_function;
-using ::mdds::matrix_element_t;
+
+const mdds::mtv::element_t element_type_custom_string = mdds::mtv::element_type_user_start;
+typedef mdds::mtv::default_element_block<element_type_custom_string, rtl::OUString> custom_string_block;
+
+namespace rtl {
+
+mdds::mtv::element_t mdds_mtv_get_element_type(const OUString&)
+{
+    return element_type_custom_string;
+}
+
+void mdds_mtv_set_value(mdds::mtv::base_element_block& block, size_t pos, const OUString& val)
+{
+    custom_string_block::set_value(block, pos, val);
+}
+
+void mdds_mtv_get_value(const mdds::mtv::base_element_block& block, size_t pos, OUString& val)
+{
+    custom_string_block::get_value(block, pos, val);
+}
+
+template<typename _Iter>
+void mdds_mtv_set_values(
+    mdds::mtv::base_element_block& block, size_t pos, const OUString&, const _Iter& it_begin, const _Iter& it_end)
+{
+    custom_string_block::set_values(block, pos, it_begin, it_end);
+}
+
+void mdds_mtv_append_value(mdds::mtv::base_element_block& block, const OUString& val)
+{
+    custom_string_block::append_value(block, val);
+}
+
+void mdds_mtv_prepend_value(mdds::mtv::base_element_block& block, const OUString& val)
+{
+    custom_string_block::prepend_value(block, val);
+}
+
+template<typename _Iter>
+void mdds_mtv_prepend_values(mdds::mtv::base_element_block& block, const OUString&, const _Iter& it_begin, const _Iter& it_end)
+{
+    custom_string_block::prepend_values(block, it_begin, it_end);
+}
+
+template<typename _Iter>
+void mdds_mtv_append_values(mdds::mtv::base_element_block& block, const OUString&, const _Iter& it_begin, const _Iter& it_end)
+{
+    custom_string_block::append_values(block, it_begin, it_end);
+}
+
+template<typename _Iter>
+void mdds_mtv_assign_values(mdds::mtv::base_element_block& dest, const OUString&, const _Iter& it_begin, const _Iter& it_end)
+{
+    custom_string_block::assign_values(dest, it_begin, it_end);
+}
+
+void mdds_mtv_get_empty_value(OUString& val)
+{
+    val = OUString();
+}
+
+template<typename _Iter>
+void mdds_mtv_insert_values(
+    mdds::mtv::base_element_block& block, size_t pos, const OUString&, const _Iter& it_begin, const _Iter& it_end)
+{
+    custom_string_block::insert_values(block, pos, it_begin, it_end);
+}
+
+mdds::mtv::base_element_block* mdds_mtv_create_new_block(size_t init_size, const OUString& val)
+{
+    return custom_string_block::create_block_with_value(init_size, val);
+}
+
+}
+
+struct custom_string_trait
+{
+    typedef OUString string_type;
+    typedef custom_string_block string_element_block;
+
+    static const mdds::mtv::element_t string_type_identifier = element_type_custom_string;
+
+    struct element_block_func
+    {
+        static mdds::mtv::base_element_block* create_new_block(
+            mdds::mtv::element_t type, size_t init_size)
+        {
+            switch (type)
+            {
+                case element_type_custom_string:
+                    return string_element_block::create_block(init_size);
+                default:
+                    return mdds::mtv::element_block_func::create_new_block(type, init_size);
+            }
+        }
+
+        static mdds::mtv::base_element_block* clone_block(const mdds::mtv::base_element_block& block)
+        {
+            switch (mdds::mtv::get_block_type(block))
+            {
+                case element_type_custom_string:
+                    return string_element_block::clone_block(block);
+                default:
+                    return mdds::mtv::element_block_func::clone_block(block);
+            }
+        }
+
+        static void delete_block(mdds::mtv::base_element_block* p)
+        {
+            if (!p)
+                return;
+
+            switch (mdds::mtv::get_block_type(*p))
+            {
+                case element_type_custom_string:
+                    string_element_block::delete_block(p);
+                break;
+                default:
+                    mdds::mtv::element_block_func::delete_block(p);
+            }
+        }
+
+        static void resize_block(mdds::mtv::base_element_block& block, size_t new_size)
+        {
+            switch (mdds::mtv::get_block_type(block))
+            {
+                case element_type_custom_string:
+                    string_element_block::resize_block(block, new_size);
+                break;
+                default:
+                    mdds::mtv::element_block_func::resize_block(block, new_size);
+            }
+        }
+
+        static void print_block(const mdds::mtv::base_element_block& block)
+        {
+            switch (mdds::mtv::get_block_type(block))
+            {
+                case element_type_custom_string:
+                    string_element_block::print_block(block);
+                break;
+                default:
+                    mdds::mtv::element_block_func::print_block(block);
+            }
+        }
+
+        static void erase(mdds::mtv::base_element_block& block, size_t pos)
+        {
+            switch (mdds::mtv::get_block_type(block))
+            {
+                case element_type_custom_string:
+                    string_element_block::erase_block(block, pos);
+                break;
+                default:
+                    mdds::mtv::element_block_func::erase(block, pos);
+            }
+        }
+
+        static void erase(mdds::mtv::base_element_block& block, size_t pos, size_t size)
+        {
+            switch (mdds::mtv::get_block_type(block))
+            {
+                case element_type_custom_string:
+                    string_element_block::erase_block(block, pos, size);
+                break;
+                default:
+                    mdds::mtv::element_block_func::erase(block, pos, size);
+            }
+        }
+
+        static void append_values_from_block(
+            mdds::mtv::base_element_block& dest, const mdds::mtv::base_element_block& src)
+        {
+            switch (mdds::mtv::get_block_type(dest))
+            {
+                case element_type_custom_string:
+                    string_element_block::append_values_from_block(dest, src);
+                break;
+                default:
+                    mdds::mtv::element_block_func::append_values_from_block(dest, src);
+            }
+        }
+
+        static void append_values_from_block(
+            mdds::mtv::base_element_block& dest, const mdds::mtv::base_element_block& src,
+            size_t begin_pos, size_t len)
+        {
+            switch (mdds::mtv::get_block_type(dest))
+            {
+                case element_type_custom_string:
+                    string_element_block::append_values_from_block(dest, src, begin_pos, len);
+                break;
+                default:
+                    mdds::mtv::element_block_func::append_values_from_block(dest, src, begin_pos, len);
+            }
+        }
+
+        static void assign_values_from_block(
+            mdds::mtv::base_element_block& dest, const mdds::mtv::base_element_block& src,
+            size_t begin_pos, size_t len)
+        {
+            switch (mdds::mtv::get_block_type(dest))
+            {
+                case element_type_custom_string:
+                    string_element_block::assign_values_from_block(dest, src, begin_pos, len);
+                break;
+                default:
+                    mdds::mtv::element_block_func::assign_values_from_block(dest, src, begin_pos, len);
+            }
+        }
+
+        static bool equal_block(
+            const mdds::mtv::base_element_block& left, const mdds::mtv::base_element_block& right)
+        {
+            if (mdds::mtv::get_block_type(left) == element_type_custom_string)
+            {
+                if (mdds::mtv::get_block_type(right) != element_type_custom_string)
+                    return false;
+
+                return string_element_block::get(left) == string_element_block::get(right);
+            }
+            else if (mdds::mtv::get_block_type(right) == element_type_custom_string)
+                return false;
+
+            return mdds::mtv::element_block_func::equal_block(left, right);
+        }
+
+        static void overwrite_values(mdds::mtv::base_element_block& block, size_t pos, size_t len)
+        {
+            switch (mdds::mtv::get_block_type(block))
+            {
+                case element_type_custom_string:
+                    // Do nothing.  The client code manages the life cycle of these cells.
+                break;
+                default:
+                    mdds::mtv::element_block_func::overwrite_values(block, pos, len);
+            }
+        }
+    };
+};
+
 
 // ============================================================================
 
 namespace {
 
-typedef ::mdds::mixed_type_matrix< ::rtl::OUString, sal_uInt8> MatrixImplType;
+typedef mdds::multi_type_matrix<custom_string_trait> MatrixImplType;
+//typedef ::mdds::mixed_type_matrix< ::rtl::OUString, sal_uInt8> MatrixImplType;
 
 struct ElemEqual : public unary_function<double, bool>
 {
@@ -105,14 +347,14 @@ struct ElemLessEqual : public unary_function<double, bool>
 template<typename _Comp>
 void compareMatrix(MatrixImplType& rMat)
 {
-    pair<size_t,size_t> aDim = rMat.size();
+    MatrixImplType::size_pair_type aDim = rMat.size();
     _Comp aComp;
-    for (size_t i = 0; i < aDim.first; ++i)
+    for (size_t i = 0; i < aDim.row; ++i)
     {
-        for (size_t j = 0; j < aDim.second; ++j)
+        for (size_t j = 0; j < aDim.column; ++j)
         {
-            matrix_element_t eType = rMat.get_type(i, j);
-            if (eType != mdds::element_numeric && eType != mdds::element_boolean)
+            mdds::mtm::element_t eType = rMat.get_type(i, j);
+            if (eType != mdds::mtm::element_numeric && eType != mdds::mtm::element_boolean)
                 // must be of numeric type (boolean can be numeric).
                 continue;
 
@@ -120,31 +362,13 @@ void compareMatrix(MatrixImplType& rMat)
             if (!::rtl::math::isFinite(fVal))
                 continue;
 
-            rMat.set_boolean(i, j, aComp(fVal));
+            bool b = aComp(fVal);
+            rMat.set(i, j, b);
         }
     }
 }
 
-::mdds::matrix_density_t toMddsDensityType(ScMatrix::DensityType eType)
-{
-    switch (eType)
-    {
-        case ScMatrix::FILLED_EMPTY:
-            return mdds::matrix_density_filled_empty;
-        case ScMatrix::FILLED_ZERO:
-            return mdds::matrix_density_filled_zero;
-        case ScMatrix::SPARSE_EMPTY:
-            return mdds::matrix_density_sparse_empty;
-        case ScMatrix::SPARSE_ZERO:
-            return mdds::matrix_density_sparse_zero;
-        default:
-            ;
-    }
-
-    // default density type
-    return mdds::matrix_density_filled_zero;
-}
-
+#if 0
 /**
  * Return a numeric value from a matrix element no matter what its type is.
  */
@@ -161,13 +385,14 @@ double getNumericValue(const MatrixImplType::element& elem)
     }
     return 0.0;
 }
+#endif
 
 }
 
 class ScMatrixImpl
 {
     MatrixImplType maMat;
-    ScMatrix::DensityType meType;
+    MatrixImplType maMatFlag;
     ScInterpreter* pErrorInterpreter;
     bool            mbCloneIfConst; // Whether the matrix is cloned with a CloneIfConst() call.
     MatrixImplType::size_pair_type  maCachedSize;
@@ -175,14 +400,14 @@ class ScMatrixImpl
     ScMatrixImpl();
     ScMatrixImpl(const ScMatrixImpl&);
 public:
-    ScMatrixImpl(SCSIZE nC, SCSIZE nR, ScMatrix::DensityType eType);
+    ScMatrixImpl(SCSIZE nC, SCSIZE nR);
+    ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal);
     ~ScMatrixImpl();
 
     void Clear();
     void SetImmutable(bool bVal);
     bool IsImmutable() const;
     void Resize(SCSIZE nC, SCSIZE nR);
-    ScMatrix::DensityType GetDensityType() const;
     void SetErrorInterpreter( ScInterpreter* p);
     ScInterpreter* GetErrorInterpreter() const { return pErrorInterpreter; }
 
@@ -204,9 +429,9 @@ public:
     sal_uInt16 GetError( SCSIZE nC, SCSIZE nR) const;
     double GetDouble(SCSIZE nC, SCSIZE nR) const;
     double GetDouble( SCSIZE nIndex) const;
-    const ::rtl::OUString& GetString(SCSIZE nC, SCSIZE nR) const;
-    const ::rtl::OUString& GetString( SCSIZE nIndex) const;
-    ::rtl::OUString GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const;
+    rtl::OUString GetString(SCSIZE nC, SCSIZE nR) const;
+    rtl::OUString GetString( SCSIZE nIndex) const;
+    rtl::OUString GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const;
     ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const;
     bool IsString( SCSIZE nIndex ) const;
     bool IsString( SCSIZE nC, SCSIZE nR ) const;
@@ -238,14 +463,11 @@ private:
     void CalcPosition(SCSIZE nIndex, SCSIZE& rC, SCSIZE& rR) const;
 };
 
-ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR, ScMatrix::DensityType eType) :
-    maMat(nR, nC, toMddsDensityType(eType)),
-    meType(eType),
-    pErrorInterpreter(NULL),
-    mbCloneIfConst(true)
-{
-    maCachedSize = maMat.size();
-}
+ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR) :
+    maMat(nR, nC), pErrorInterpreter(NULL), mbCloneIfConst(true) {}
+
+ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal) :
+    maMat(nR, nC, fInitVal), pErrorInterpreter(NULL), mbCloneIfConst(true) {}
 
 ScMatrixImpl::~ScMatrixImpl()
 {
@@ -255,7 +477,6 @@ ScMatrixImpl::~ScMatrixImpl()
 void ScMatrixImpl::Clear()
 {
     maMat.clear();
-    maCachedSize = maMat.size();
 }
 
 void ScMatrixImpl::SetImmutable(bool bVal)
@@ -271,12 +492,6 @@ bool ScMatrixImpl::IsImmutable() const
 void ScMatrixImpl::Resize(SCSIZE nC, SCSIZE nR)
 {
     maMat.resize(nR, nC);
-    maCachedSize = maMat.size();
-}
-
-ScMatrix::DensityType ScMatrixImpl::GetDensityType() const
-{
-    return meType;
 }
 
 void ScMatrixImpl::SetErrorInterpreter( ScInterpreter* p)
@@ -286,35 +501,39 @@ void ScMatrixImpl::SetErrorInterpreter( ScInterpreter* p)
 
 void ScMatrixImpl::GetDimensions( SCSIZE& rC, SCSIZE& rR) const
 {
-    rR = maCachedSize.first;
-    rC = maCachedSize.second;
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    rR = aSize.row;
+    rC = aSize.column;
 }
 
 SCSIZE ScMatrixImpl::GetElementCount() const
 {
-    return maCachedSize.first * maCachedSize.second;
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    return aSize.row * aSize.column;
 }
 
 bool ScMatrixImpl::ValidColRow( SCSIZE nC, SCSIZE nR) const
 {
-    return nR < maCachedSize.first && nC < maCachedSize.second;
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    return nR < aSize.row && nC < aSize.column;
 }
 
 bool ScMatrixImpl::ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const
 {
-    if (maCachedSize.second == 1 && maCachedSize.first == 1)
+    MatrixImplType::size_pair_type aSize = maMat.size();
+    if (aSize.column == 1 && aSize.row == 1)
     {
         rC = 0;
         rR = 0;
         return true;
     }
-    else if (maCachedSize.second == 1 && rR < maCachedSize.first)
+    else if (aSize.column == 1 && rR < aSize.row)
     {
         // single column matrix.
         rC = 0;
         return true;
     }
-    else if (maCachedSize.first == 1 && rC < maCachedSize.second)
+    else if (aSize.row == 1 && rC < aSize.column)
     {
         // single row matrix.
         rR = 0;
@@ -337,7 +556,7 @@ void ScMatrixImpl::SetErrorAtInterpreter( sal_uInt16 nError ) const
 void ScMatrixImpl::PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
 {
     if (ValidColRow( nC, nR))
-        maMat.set_numeric(nR, nC, fVal);
+        maMat.set(nR, nC, fVal);
     else
     {
         OSL_FAIL("ScMatrixImpl::PutDouble: dimension error");
@@ -354,7 +573,7 @@ void ScMatrixImpl::PutDouble( double fVal, SCSIZE nIndex)
 void ScMatrixImpl::PutString(const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR)
 {
     if (ValidColRow( nC, nR))
-        maMat.set_string(nR, nC, new ::rtl::OUString(rStr));
+        maMat.set(nR, nC, rtl::OUString(rStr));
     else
     {
         OSL_FAIL("ScMatrixImpl::PutString: dimension error");
@@ -373,7 +592,7 @@ void ScMatrixImpl::PutEmpty(SCSIZE nC, SCSIZE nR)
     if (ValidColRow( nC, nR))
     {
         maMat.set_empty(nR, nC);
-        maMat.clear_flag(nR, nC); // zero flag to indicate that this is 'empty', not 'empty path'.
+        maMatFlag.set(nR, nC, false); // zero flag to indicate that this is 'empty', not 'empty path'.
     }
     else
     {
@@ -386,7 +605,7 @@ void ScMatrixImpl::PutEmptyPath(SCSIZE nC, SCSIZE nR)
     if (ValidColRow( nC, nR))
     {
         maMat.set_empty(nR, nC);
-        maMat.set_flag(nR, nC, 1); // non-zero flag to indicate empty 'path'.
+        maMatFlag.set(nR, nC, true); // non-zero flag to indicate empty 'path'.
     }
     else
     {
@@ -396,13 +615,13 @@ void ScMatrixImpl::PutEmptyPath(SCSIZE nC, SCSIZE nR)
 
 void ScMatrixImpl::PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR )
 {
-    maMat.set_numeric(nR, nC, CreateDoubleError(nErrorCode));
+    maMat.set(nR, nC, CreateDoubleError(nErrorCode));
 }
 
 void ScMatrixImpl::PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR)
 {
     if (ValidColRow( nC, nR))
-        maMat.set_boolean(nR, nC, bVal);
+        maMat.set(nR, nC, bVal);
     else
     {
         OSL_FAIL("ScMatrixImpl::PutBoolean: dimension error");
@@ -450,15 +669,15 @@ double ScMatrixImpl::GetDouble( SCSIZE nIndex) const
     return GetDouble(nC, nR);
 }
 
-const ::rtl::OUString& ScMatrixImpl::GetString(SCSIZE nC, SCSIZE nR) const
+rtl::OUString ScMatrixImpl::GetString(SCSIZE nC, SCSIZE nR) const
 {
     if (ValidColRowOrReplicated( nC, nR ))
     {
         switch (maMat.get_type(nR, nC))
         {
-            case ::mdds::element_string:
-                return *maMat.get_string(nR, nC);
-            case ::mdds::element_empty:
+            case mdds::mtm::element_string:
+                return maMat.get<rtl::OUString>(nR, nC);
+            case mdds::mtm::element_empty:
                 return EMPTY_OUSTRING;
             default:
                 SetErrorAtInterpreter( GetError(nC, nR));
@@ -472,14 +691,14 @@ const ::rtl::OUString& ScMatrixImpl::GetString(SCSIZE nC, SCSIZE nR) const
     return EMPTY_OUSTRING;
 }
 
-const ::rtl::OUString& ScMatrixImpl::GetString( SCSIZE nIndex) const
+rtl::OUString ScMatrixImpl::GetString( SCSIZE nIndex) const
 {
     SCSIZE nC, nR;
     CalcPosition(nIndex, nC, nR);
     return GetString(nC, nR);
 }
 
-::rtl::OUString ScMatrixImpl::GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const
+rtl::OUString ScMatrixImpl::GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const
 {
     if (!ValidColRowOrReplicated( nC, nR ))
     {
@@ -521,24 +740,24 @@ ScMatrixValue ScMatrixImpl::Get(SCSIZE nC, SCSIZE nR) const
     ScMatrixValue aVal;
     if (ValidColRowOrReplicated(nC, nR))
     {
-        matrix_element_t eType = maMat.get_type(nR, nC);
+        mdds::mtm::element_t eType = maMat.get_type(nR, nC);
         switch (eType)
         {
-            case mdds::element_boolean:
+            case mdds::mtm::element_boolean:
                 aVal.nType = SC_MATVAL_BOOLEAN;
                 aVal.fVal = maMat.get_boolean(nR, nC);
             break;
-            case mdds::element_numeric:
+            case mdds::mtm::element_numeric:
                 aVal.nType = SC_MATVAL_VALUE;
                 aVal.fVal = maMat.get_numeric(nR, nC);
             break;
-            case mdds::element_string:
+            case mdds::mtm::element_string:
                 aVal.nType = SC_MATVAL_STRING;
-                aVal.pS = maMat.get_string(nR, nC);
+                aVal.pS = &EMPTY_OUSTRING;
             break;
-            case mdds::element_empty:
+            case mdds::mtm::element_empty:
                 // Empty path equals empty plus flag.
-                aVal.nType = maMat.get_flag(nR, nC) ? SC_MATVAL_EMPTYPATH : SC_MATVAL_EMPTY;
+                aVal.nType = maMatFlag.get<bool>(nR, nC) ? SC_MATVAL_EMPTYPATH : SC_MATVAL_EMPTY;
                 aVal.fVal = 0.0;
             default:
                 ;
@@ -563,8 +782,8 @@ bool ScMatrixImpl::IsString( SCSIZE nC, SCSIZE nR ) const
     ValidColRowReplicated( nC, nR );
     switch (maMat.get_type(nR, nC))
     {
-        case mdds::element_empty:
-        case mdds::element_string:
+        case mdds::mtm::element_empty:
+        case mdds::mtm::element_string:
             return true;
         default:
             ;
@@ -577,14 +796,14 @@ bool ScMatrixImpl::IsEmpty( SCSIZE nC, SCSIZE nR ) const
     // Flag must be zero for this to be an empty element, instead of being an
     // empty path element.
     ValidColRowReplicated( nC, nR );
-    return maMat.get_type(nR, nC) == ::mdds::element_empty && maMat.get_flag(nR, nC) == 0;
+    return maMat.get_type(nR, nC) == mdds::mtm::element_empty && !maMatFlag.get<bool>(nR, nC);
 }
 
 bool ScMatrixImpl::IsEmptyPath( SCSIZE nC, SCSIZE nR ) const
 {
     // 'Empty path' is empty plus non-zero flag.
     if (ValidColRowOrReplicated( nC, nR ))
-        return maMat.get_type(nR, nC) == ::mdds::element_empty && maMat.get_flag(nR, nC) != 0;
+        return maMat.get_type(nR, nC) == mdds::mtm::element_empty && maMatFlag.get<bool>(nR, nC);
     else
         return true;
 }
@@ -601,8 +820,8 @@ bool ScMatrixImpl::IsValue( SCSIZE nC, SCSIZE nR ) const
     ValidColRowReplicated(nC, nR);
     switch (maMat.get_type(nR, nC))
     {
-        case mdds::element_boolean:
-        case mdds::element_numeric:
+        case mdds::mtm::element_boolean:
+        case mdds::mtm::element_numeric:
             return true;
         default:
             ;
@@ -615,9 +834,9 @@ bool ScMatrixImpl::IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const
     ValidColRowReplicated(nC, nR);
     switch (maMat.get_type(nR, nC))
     {
-        case mdds::element_boolean:
-        case mdds::element_numeric:
-        case mdds::element_empty:
+        case mdds::mtm::element_boolean:
+        case mdds::mtm::element_numeric:
+        case mdds::mtm::element_empty:
             return true;
         default:
             ;
@@ -628,7 +847,7 @@ bool ScMatrixImpl::IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const
 bool ScMatrixImpl::IsBoolean( SCSIZE nC, SCSIZE nR ) const
 {
     ValidColRowReplicated( nC, nR );
-    return maMat.get_type(nR, nC) == ::mdds::element_boolean;
+    return maMat.get_type(nR, nC) == mdds::mtm::element_boolean;
 }
 
 bool ScMatrixImpl::IsNumeric() const
@@ -638,22 +857,20 @@ bool ScMatrixImpl::IsNumeric() const
 
 void ScMatrixImpl::MatCopy(ScMatrixImpl& mRes) const
 {
-    if (maCachedSize.first > mRes.maCachedSize.first || maCachedSize.second > mRes.maCachedSize.second)
+    if (maMat.size().row > mRes.maMat.size().row || maMat.size().column > mRes.maMat.size().column)
     {
         // destination matrix is not large enough.
         OSL_FAIL("ScMatrixImpl::MatCopy: dimension error");
         return;
     }
 
-    mRes.maMat.assign(maMat);
-    mRes.maCachedSize = mRes.maMat.size();
+    mRes.maMat.copy(maMat);
 }
 
 void ScMatrixImpl::MatTrans(ScMatrixImpl& mRes) const
 {
     mRes.maMat = maMat;
     mRes.maMat.transpose();
-    mRes.maCachedSize = mRes.maMat.size();
 }
 
 void ScMatrixImpl::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 )
@@ -720,13 +937,13 @@ template <typename _Evaluator>
 bool EvalMatrix(const MatrixImplType& rMat)
 {
     _Evaluator aEval;
-    size_t nRows = rMat.size().first, nCols = rMat.size().second;
+    size_t nRows = rMat.size().row, nCols = rMat.size().column;
     for (size_t i = 0; i < nRows; ++i)
     {
         for (size_t j = 0; j < nCols; ++j)
         {
-            matrix_element_t eType = rMat.get_type(i, j);
-            if (eType != mdds::element_numeric && eType != mdds::element_boolean)
+            mdds::mtm::element_t eType = rMat.get_type(i, j);
+            if (eType != mdds::mtm::element_numeric && eType != mdds::mtm::element_boolean)
                 // assuming a CompareMat this is an error
                 return CreateDoubleError(errIllegalArgument);
 
@@ -758,170 +975,41 @@ double ScMatrixImpl::Or() const
     return EvalMatrix<OrEvaluator>(maMat);
 }
 
-namespace {
-
-/**
- * Function object to sum all numeric elements (including boolean).  It
- * stores the first non-zero element value into maRes.mfFirst while the rest
- * into maRes.mfRest.  This weird requirement comes from
- * ScInterpreter::IterateParameters.
- */
-class SumElements : public unary_function<void, MatrixImplType::element>
-{
-    ScMatrix::IterateResult maRes;
-    bool mbTextAsZero;
-public:
-    SumElements(bool bTextAsZero) : maRes(0.0, 0.0, 0), mbTextAsZero(bTextAsZero) {}
-
-    ScMatrix::IterateResult getResult() const { return maRes; }
-    void operator() (const MatrixImplType::element& elem)
-    {
-        switch (elem.m_type)
-        {
-            case mdds::element_boolean:
-                if (elem.m_boolean)
-                {
-                    if (maRes.mfFirst)
-                        maRes.mfFirst = 1.0;
-                    else
-                        maRes.mfRest += 1.0;
-                }
-                ++maRes.mnCount;
-            break;
-            case mdds::element_numeric:
-                if (elem.m_numeric != 0.0)
-                {
-                    if (maRes.mfFirst)
-                        maRes.mfFirst = elem.m_numeric;
-                    else
-                        maRes.mfRest += elem.m_numeric;
-                }
-                ++maRes.mnCount;
-            break;
-            case mdds::element_string:
-                if (mbTextAsZero)
-                    ++maRes.mnCount;
-            default:
-                ;
-        }
-    }
-};
-
-class SumSquareElements : public unary_function<void, MatrixImplType::element>
-{
-    ScMatrix::IterateResult maRes;
-    bool mbTextAsZero;
-public:
-    SumSquareElements(bool bTextAsZero) : maRes(0.0, 0.0, 0), mbTextAsZero(bTextAsZero) {}
-    ScMatrix::IterateResult getResult() const { return maRes; }
-    void operator() (const MatrixImplType::element& elem)
-    {
-        if (elem.m_type == ::mdds::element_empty)
-            return;
-
-        if (elem.m_type == ::mdds::element_string)
-        {
-            if (mbTextAsZero)
-                ++maRes.mnCount;
-            return;
-        }
-
-        double val = getNumericValue(elem);
-        maRes.mfRest += val*val;
-        ++maRes.mnCount;
-    }
-};
-
-/**
- * Multiply all boolean and numeric elements.  It skips empty elements, and
- * optionally string elements if specified.  When text as zero option is
- * specified, it treats string elements as if they have values of zero.
- */
-class MultiplyElements : public unary_function<void, MatrixImplType::element>
-{
-    ScMatrix::IterateResult maRes;
-    bool mbTextAsZero;
-public:
-    MultiplyElements(bool bTextAsZero) : maRes(0.0, 1.0, 0), mbTextAsZero(bTextAsZero) {}
-    ScMatrix::IterateResult getResult() const { return maRes; }
-
-    void operator() (const MatrixImplType::element& elem)
-    {
-        if (elem.m_type == ::mdds::element_string)
-        {
-            ++maRes.mnCount;
-            if (mbTextAsZero)
-                maRes.mfRest = 0.0;
-        }
-        else if (elem.m_type != ::mdds::element_empty)
-        {
-            ++maRes.mnCount;
-            maRes.mfRest *= getNumericValue(elem);
-        }
-    }
-};
-
-/**
- * Predicate for counting only boolean, numeric, and optionally string
- * elements.
- */
-class CountNonEmptyElements : public unary_function<bool, MatrixImplType::element>
-{
-    const bool mbCountString;
-public:
-    CountNonEmptyElements(bool bCountString) : mbCountString(bCountString) {}
-    bool operator() (const MatrixImplType::element& elem) const
-    {
-        switch (elem.m_type)
-        {
-            case mdds::element_boolean:
-            case mdds::element_numeric:
-                return true;
-            case mdds::element_string:
-                return mbCountString;
-            default:
-                ;
-        }
-        return false;
-    }
-};
-
-}
-
 ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const
 {
-    return for_each(maMat.begin(), maMat.end(), SumElements(bTextAsZero)).getResult();
+    return ScMatrix::IterateResult(0, 0, 0);
 }
 
 ScMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const
 {
-    return for_each(maMat.begin(), maMat.end(), SumSquareElements(bTextAsZero)).getResult();
+    return ScMatrix::IterateResult(0, 0, 0);
 }
 
 ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const
 {
-    return for_each(maMat.begin(), maMat.end(), MultiplyElements(bTextAsZero)).getResult();
+    return ScMatrix::IterateResult(0, 0, 0);
 }
 
 size_t ScMatrixImpl::Count(bool bCountStrings) const
 {
-    return count_if(maMat.begin(), maMat.end(), CountNonEmptyElements(bCountStrings));
+    return 0;
 }
 
 void ScMatrixImpl::CalcPosition(SCSIZE nIndex, SCSIZE& rC, SCSIZE& rR) const
 {
-    SCSIZE nRowSize = maCachedSize.first;
+    SCSIZE nRowSize = maMat.size().row;
     rC = nIndex / nRowSize;
     rR = nIndex - rC*nRowSize;
 }
 
 // ============================================================================
 
-ScMatrix::ScMatrix( SCSIZE nC, SCSIZE nR, DensityType eType) :
-    pImpl(new ScMatrixImpl(nC, nR, eType)),
-    nRefCnt(0)
-{
-}
+ScMatrix::ScMatrix( SCSIZE nC, SCSIZE nR) :
+    pImpl(new ScMatrixImpl(nC, nR)), nRefCnt(0) {}
+
+ScMatrix::ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal) :
+    pImpl(new ScMatrixImpl(nC, nR, fInitVal)), nRefCnt(0) {}
+
 ScMatrix::~ScMatrix()
 {
     delete pImpl;
@@ -929,14 +1017,9 @@ ScMatrix::~ScMatrix()
 
 ScMatrix* ScMatrix::Clone() const
 {
-    return Clone(GetDensityType());
-}
-
-ScMatrix* ScMatrix::Clone( DensityType eType) const
-{
     SCSIZE nC, nR;
     pImpl->GetDimensions(nC, nR);
-    ScMatrix* pScMat = new ScMatrix(nC, nR, eType);
+    ScMatrix* pScMat = new ScMatrix(nC, nR);
     MatCopy(*pScMat);
     pScMat->SetErrorInterpreter(pImpl->GetErrorInterpreter());    // TODO: really?
     return pScMat;
@@ -957,19 +1040,14 @@ void ScMatrix::Resize( SCSIZE nC, SCSIZE nR)
     pImpl->Resize(nC, nR);
 }
 
-ScMatrix* ScMatrix::CloneAndExtend( SCSIZE nNewCols, SCSIZE nNewRows, DensityType eType ) const
+ScMatrix* ScMatrix::CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const
 {
-    ScMatrix* pScMat = new ScMatrix( nNewCols, nNewRows, eType);
+    ScMatrix* pScMat = new ScMatrix(nNewCols, nNewRows);
     MatCopy(*pScMat);
     pScMat->SetErrorInterpreter(pImpl->GetErrorInterpreter());
     return pScMat;
 }
 
-ScMatrix::DensityType ScMatrix::GetDensityType() const
-{
-    return pImpl->GetDensityType();
-}
-
 void ScMatrix::SetErrorInterpreter( ScInterpreter* p)
 {
     pImpl->SetErrorInterpreter(p);
@@ -1055,12 +1133,12 @@ double ScMatrix::GetDouble( SCSIZE nIndex) const
     return pImpl->GetDouble(nIndex);
 }
 
-const ::rtl::OUString& ScMatrix::GetString(SCSIZE nC, SCSIZE nR) const
+rtl::OUString ScMatrix::GetString(SCSIZE nC, SCSIZE nR) const
 {
     return pImpl->GetString(nC, nR);
 }
 
-const ::rtl::OUString& ScMatrix::GetString( SCSIZE nIndex) const
+rtl::OUString ScMatrix::GetString( SCSIZE nIndex) const
 {
     return pImpl->GetString(nIndex);
 }
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index e244807..101a8ac 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -626,8 +626,7 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
         }
 
         ScMatrixRef xMat = new ScMatrix(
-            static_cast<SCSIZE>(nDataCol2-nDataCol1+1),
-            static_cast<SCSIZE>(nDataRow2-nDataRow1+1), ScMatrix::SPARSE_EMPTY);
+            static_cast<SCSIZE>(nDataCol2-nDataCol1+1), static_cast<SCSIZE>(nDataRow2-nDataRow1+1));
 
         // Only fill non-empty cells, for better performance.
         vector<SCROW> aRows;
@@ -1383,8 +1382,7 @@ static ScTokenArray* lcl_convertToTokenArray(const ScDocument* pSrcDoc, ScRange&
             pUsedRange.reset(new ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
 
         ScMatrixRef xMat = new ScMatrix(
-            static_cast<SCSIZE>(nCol2-nCol1+1),
-            static_cast<SCSIZE>(nRow2-nRow1+1), ScMatrix::SPARSE_EMPTY);
+            static_cast<SCSIZE>(nCol2-nCol1+1), static_cast<SCSIZE>(nRow2-nRow1+1));
 
         for (SCCOL nCol = nDataCol1; nCol <= nDataCol2; ++nCol)
         {


More information about the Libreoffice-commits mailing list