[Libreoffice-commits] core.git: sc/inc sc/source

Łukasz Hryniuk lukasz.hryniuk at wp.pl
Mon Mar 9 14:31:26 PDT 2015


 sc/inc/scmatrix.hxx              |    8 +
 sc/source/core/tool/interpr1.cxx |   26 -----
 sc/source/core/tool/interpr5.cxx |   55 ++----------
 sc/source/core/tool/scmatrix.cxx |  170 ++++++++++++++++++++++++++-------------
 4 files changed, 134 insertions(+), 125 deletions(-)

New commits:
commit 1c2405ba44c5a146188c19e235f857ab18ea05f0
Author: Łukasz Hryniuk <lukasz.hryniuk at wp.pl>
Date:   Wed Mar 4 22:12:11 2015 +0100

    tdf#89387 General functor and basic operations
    
    Add a functor MatOp and ScMatrix methods for scalar-matrix operations,
    both unary and binary. It can be used for operations which modify each
    element for the matrix (in constrast to accumulating ones, like ScGCD
    or ScAmpersand).
    
    Split method for addition and substraction into two methods for
    consistency and simplicity.
    
    Change-Id: Ic040233429ee120ac325d7baf31a70bba232041d
    Reviewed-on: https://gerrit.libreoffice.org/14749
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 255d452..e85054e 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -387,7 +387,13 @@ public:
     void GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero = true ) const;
     void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const;
 
-    void SubAddOp(bool bSub, double fVal, svl::SharedString aString, ScMatrix& rMat);
+    void NotOp(svl::SharedString aString, ScMatrix& rMat);
+    void NegOp(svl::SharedString aString, ScMatrix& rMat);
+    void AddOp(svl::SharedString aString, double fVal, ScMatrix& rMat);
+    void SubOp(bool bFlag, svl::SharedString aString, double fVal, ScMatrix& rMat);
+    void MulOp(svl::SharedString aString, double fVal, ScMatrix& rMat);
+    void DivOp(bool bFlag, svl::SharedString aString, double fVal, ScMatrix& rMat);
+    void PowOp(bool bFlag, svl::SharedString aString, double fVal, ScMatrix& rMat);
 
     ScMatrix& operator+= ( const ScMatrix& r );
 
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 4082491..e7fd644 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -1500,17 +1500,8 @@ void ScInterpreter::ScNeg()
                     PushIllegalArgument();
                 else
                 {
-                    for (SCSIZE i = 0; i < nC; ++i)
-                    {
-                        for (SCSIZE j = 0; j < nR; ++j)
-                        {
-                            if ( pMat->IsValueOrEmpty(i,j) )
-                                pResMat->PutDouble( -pMat->GetDouble(i,j), i, j );
-                            else
-                                pResMat->PutString(
-                                    mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), i, j);
-                        }
-                    }
+                    svl::SharedString aString = mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE));
+                    pMat->NegOp(aString, *pResMat);
                     PushMatrix( pResMat );
                 }
             }
@@ -1554,17 +1545,8 @@ void ScInterpreter::ScNot()
                     PushIllegalArgument();
                 else
                 {
-                    for (SCSIZE i = 0; i < nC; ++i)
-                    {
-                        for (SCSIZE j = 0; j < nR; ++j)
-                        {
-                            if ( pMat->IsValueOrEmpty(i,j) )
-                                pResMat->PutDouble( double(pMat->GetDouble(i,j) == 0.0), i, j );
-                            else
-                                pResMat->PutString(
-                                    mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), i, j);
-                        }
-                    }
+                    svl::SharedString aString = mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE));
+                    pMat->NotOp(aString, *pResMat);
                     PushMatrix( pResMat );
                 }
             }
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index 38863a0..81bcdfc 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -1284,20 +1284,13 @@ void ScInterpreter::CalculateAddSub(bool _bSub)
         if (pResMat)
         {
             svl::SharedString aString = mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE));
-            if (bFlag || !_bSub )
+            if (_bSub)
             {
-                if (_bSub)
-                {
-                    pMat->SubAddOp(true, fVal, aString, *pResMat);
-                }
-                else
-                {
-                    pMat->SubAddOp(false, fVal, aString, *pResMat);
-                }
+                pMat->SubOp(bFlag, aString, fVal, *pResMat);
             }
             else
             {
-                pMat->SubAddOp(false, -fVal, aString, *pResMat);
+                pMat->AddOp(aString, fVal, *pResMat);
             }
             PushMatrix(pResMat);
         }
@@ -1476,12 +1469,8 @@ void ScInterpreter::ScMul()
         ScMatrixRef pResMat = GetNewMat(nC, nR);
         if (pResMat)
         {
-            SCSIZE nCount = nC * nR;
-            for ( SCSIZE i = 0; i < nCount; i++ )
-                if (pMat->IsValue(i))
-                    pResMat->PutDouble(pMat->GetDouble(i)*fVal, i);
-                else
-                    pResMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), i);
+            svl::SharedString aString = mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE));
+            pMat->MulOp(aString, fVal, *pResMat);
             PushMatrix(pResMat);
         }
         else
@@ -1554,21 +1543,8 @@ void ScInterpreter::ScDiv()
         ScMatrixRef pResMat = GetNewMat(nC, nR);
         if (pResMat)
         {
-            SCSIZE nCount = nC * nR;
-            if (bFlag)
-            {   for ( SCSIZE i = 0; i < nCount; i++ )
-                    if (pMat->IsValue(i))
-                        pResMat->PutDouble( div( fVal, pMat->GetDouble(i)), i);
-                    else
-                        pResMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), i);
-            }
-            else
-            {   for ( SCSIZE i = 0; i < nCount; i++ )
-                    if (pMat->IsValue(i))
-                        pResMat->PutDouble( div( pMat->GetDouble(i), fVal), i);
-                    else
-                        pResMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), i);
-            }
+            svl::SharedString aString = mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE));
+            pMat->DivOp(bFlag, aString, fVal, *pResMat);
             PushMatrix(pResMat);
         }
         else
@@ -1633,21 +1609,8 @@ void ScInterpreter::ScPow()
         ScMatrixRef pResMat = GetNewMat(nC, nR);
         if (pResMat)
         {
-            SCSIZE nCount = nC * nR;
-            if (bFlag)
-            {   for ( SCSIZE i = 0; i < nCount; i++ )
-                    if (pMat->IsValue(i))
-                        pResMat->PutDouble(pow(fVal,pMat->GetDouble(i)), i);
-                    else
-                        pResMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), i);
-            }
-            else
-            {   for ( SCSIZE i = 0; i < nCount; i++ )
-                    if (pMat->IsValue(i))
-                        pResMat->PutDouble(pow(pMat->GetDouble(i),fVal), i);
-                    else
-                        pResMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), i);
-            }
+            svl::SharedString aString = mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE));
+            pMat->PowOp(bFlag, aString, fVal, *pResMat);
             PushMatrix(pResMat);
         }
         else
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 8273f44..5f6e155 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -24,6 +24,7 @@
 #include "interpre.hxx"
 #include "mtvelements.hxx"
 #include "compare.hxx"
+#include "math.hxx"
 
 #include <boost/noncopyable.hpp>
 #include <svl/zforlist.hxx>
@@ -35,6 +36,7 @@
 
 #include <vector>
 #include <limits>
+#include <type_traits>
 
 #include <mdds/multi_type_matrix.hpp>
 #include <mdds/multi_type_vector_types.hpp>
@@ -1893,12 +1895,12 @@ struct return_type<char>
 
 }
 
-template<typename T, typename U>
+template<typename T, typename U, typename return_type>
 struct wrapped_iterator
 {
     typedef ::std::bidirectional_iterator_tag iterator_category;
     typedef typename T::const_iterator::value_type old_value_type;
-    typedef typename Op::return_type<old_value_type>::type value_type;
+    typedef return_type value_type;
     typedef value_type* pointer;
     typedef value_type& reference;
     typedef typename T::const_iterator::difference_type difference_type;
@@ -1973,7 +1975,7 @@ public:
     }
 };
 
-template<typename T, typename U>
+template<typename T, typename U, typename return_type>
 struct MatrixIteratorWrapper
 {
 private:
@@ -1988,14 +1990,14 @@ public:
     {
     }
 
-    wrapped_iterator<T, U> begin()
+    wrapped_iterator<T, U, return_type> begin()
     {
-        return wrapped_iterator<T, U>(m_itBegin, maOp);
+        return wrapped_iterator<T, U, return_type>(m_itBegin, maOp);
     }
 
-    wrapped_iterator<T, U> end()
+    wrapped_iterator<T, U, return_type> end()
     {
-        return wrapped_iterator<T, U>(m_itEnd, maOp);
+        return wrapped_iterator<T, U, return_type>(m_itEnd, maOp);
     }
 };
 
@@ -2025,7 +2027,7 @@ public:
 
                 block_type::const_iterator it = block_type::begin(*node.data);
                 block_type::const_iterator itEnd = block_type::end(*node.data);
-                MatrixIteratorWrapper<block_type, T> aFunc(it, itEnd, maOp);
+                MatrixIteratorWrapper<block_type, T, typename T::number_value_type> aFunc(it, itEnd, maOp);
                 pos = mrMat.set(pos,aFunc.begin(), aFunc.end());
                 ++pos.first;
             }
@@ -2037,7 +2039,7 @@ public:
                 block_type::const_iterator it = block_type::begin(*node.data);
                 block_type::const_iterator itEnd = block_type::end(*node.data);
 
-                MatrixIteratorWrapper<block_type, T> aFunc(it, itEnd, maOp);
+                MatrixIteratorWrapper<block_type, T, typename T::number_value_type> aFunc(it, itEnd, maOp);
                 pos = mrMat.set(pos, aFunc.begin(), aFunc.end());
                 ++pos.first;
             }
@@ -2049,7 +2051,7 @@ public:
                 block_type::const_iterator it = block_type::begin(*node.data);
                 block_type::const_iterator itEnd = block_type::end(*node.data);
 
-                MatrixIteratorWrapper<block_type, T> aFunc(it, itEnd, maOp);
+                MatrixIteratorWrapper<block_type, T, typename T::string_value_type> aFunc(it, itEnd, maOp);
                 pos = mrMat.set(pos, aFunc.begin(), aFunc.end());
                 ++pos.first;
             }
@@ -2059,7 +2061,7 @@ public:
                 if (maOp.useFunctionForEmpty())
                 {
                     std::vector<char> aVec(node.size);
-                    MatrixIteratorWrapper<std::vector<char>, T> aFunc(aVec.begin(), aVec.end(), maOp);
+                    MatrixIteratorWrapper<std::vector<char>, T, typename T::empty_value_type> aFunc(aVec.begin(), aVec.end(), maOp);
                     pos = mrMat.set(pos, aFunc.begin(), aFunc.end());
                     ++pos.first;
                 }
@@ -2510,30 +2512,64 @@ void ScMatrix::MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const
     pImpl->MergeDoubleArray(rArray, eOp);
 }
 
-namespace {
+namespace matop {
+
+/**
+ * COp struct is used in MatOp class to provide (through template specialization)
+ * different actions for empty entries in a matrix.
+ */
+template <typename T, typename S>
+struct COp {};
+
+template <typename T>
+struct COp<T, svl::SharedString>
+{
+    svl::SharedString operator()(char, T /*aOp*/, const svl::SharedString& aString) const
+    {
+        return aString;
+    }
+};
+
+template <typename T>
+struct COp<T, double>
+{
+    double operator()(char, T aOp, const svl::SharedString& /*aString*/) const
+    {
+        return aOp(double{}, double{});
+    }
+};
 
-struct AddOp
+template<typename TOp, typename TEmptyRes=svl::SharedString, typename TRet=double>
+struct MatOp
 {
 private:
-    double mnVal;
+    TOp maOp;
     svl::SharedString maString;
+    double mfVal;
+    bool mbUseForEmpty;
+    COp<TOp, TEmptyRes> maCOp;
 
 public:
 
-    AddOp(double nVal, svl::SharedString aString):
-        mnVal(nVal),
-        maString(aString)
-    {
-    }
+    typedef TEmptyRes empty_value_type;
+    typedef TRet number_value_type;
+    typedef svl::SharedString string_value_type;
+
+    MatOp(TOp op, svl::SharedString aString, double fVal=0.0, bool bUseForEmpty=true):
+        maOp(op),
+        maString(aString),
+        mfVal(fVal),
+        mbUseForEmpty(bUseForEmpty)
+    { }
 
-    double operator()(double nVal) const
+    TRet operator()(double fVal) const
     {
-        return nVal + mnVal;
+        return maOp(fVal, mfVal);
     }
 
-    double operator()(bool bVal) const
+    TRet operator()(bool bVal) const
     {
-        return mnVal + (double)bVal;
+        return maOp((double)bVal, mfVal);
     }
 
     svl::SharedString operator()(const svl::SharedString&) const
@@ -2541,69 +2577,91 @@ public:
         return maString;
     }
 
-    svl::SharedString operator()(char) const
+    TEmptyRes operator()(char) const
     {
-        return maString;
+        return maCOp(char{}, maOp, maString);
     }
 
     bool useFunctionForEmpty() const
     {
-        return true;
+        return mbUseForEmpty;
     }
 };
 
-struct SubOp
+}
+
+void ScMatrix::NotOp(svl::SharedString aString, ScMatrix& rMat)
 {
-private:
-    double mnVal;
-    svl::SharedString maString;
+    auto not_ = [&](double a, double){return double(a == 0.0);};
+    matop::MatOp<decltype(not_), double> aOp(not_, aString);
+    pImpl->ApplyOperation(aOp, *rMat.pImpl);
+}
 
-public:
+void ScMatrix::NegOp(svl::SharedString aString, ScMatrix& rMat)
+{
+    auto neg_ = [&](double a, double){return -a;};
+    matop::MatOp<decltype(neg_), double> aOp(neg_, aString);
+    pImpl->ApplyOperation(aOp, *rMat.pImpl);
+}
 
-    SubOp(double nVal, svl::SharedString aString):
-        mnVal(nVal),
-        maString(aString)
-    {
-    }
+void ScMatrix::AddOp(svl::SharedString aString, double fVal, ScMatrix& rMat)
+{
+    auto add_ = [&](double a, double b){return a + b;};
+    matop::MatOp<decltype(add_)> aOp(add_, aString, fVal);
+    pImpl->ApplyOperation(aOp, *rMat.pImpl);
+}
 
-    double operator()(double nVal) const
+void ScMatrix::SubOp(bool bFlag, svl::SharedString aString, double fVal, ScMatrix& rMat)
+{
+    if (bFlag)
     {
-        return mnVal - nVal;
+        auto sub_ = [&](double a, double b){return b - a;};
+        matop::MatOp<decltype(sub_)> aOp(sub_, aString, fVal);
+        pImpl->ApplyOperation(aOp, *rMat.pImpl);
     }
-
-    double operator()(bool bVal) const
+    else
     {
-        return mnVal - (double)bVal;
+        auto sub_ = [&](double a, double b){return a - b;};
+        matop::MatOp<decltype(sub_)> aOp(sub_, aString, fVal);
+        pImpl->ApplyOperation(aOp, *rMat.pImpl);
     }
+}
 
-    svl::SharedString operator()(const svl::SharedString&) const
-    {
-        return maString;
-    }
+void ScMatrix::MulOp(svl::SharedString aString, double fVal, ScMatrix& rMat)
+{
+    auto mul_ = [&](double a, double b){return a * b;};
+    matop::MatOp<decltype(mul_)> aOp(mul_, aString, fVal);
+    pImpl->ApplyOperation(aOp, *rMat.pImpl);
+}
 
-    svl::SharedString operator()(char) const
+void ScMatrix::DivOp(bool bFlag, svl::SharedString aString, double fVal, ScMatrix& rMat)
+{
+    if (bFlag)
     {
-        return maString;
+        auto div_ = [&](double a, double b){return sc::div(b, a);};
+        matop::MatOp<decltype(div_), svl::SharedString> aOp(div_, aString, fVal);
+        pImpl->ApplyOperation(aOp, *rMat.pImpl);
     }
-
-    bool useFunctionForEmpty() const
+    else
     {
-        return true;
+        auto div_ = [&](double a, double b){return sc::div(a, b);};
+        matop::MatOp<decltype(div_), svl::SharedString> aOp(div_, aString, fVal);
+        pImpl->ApplyOperation(aOp, *rMat.pImpl);
     }
-};
-
 }
 
-void ScMatrix::SubAddOp(bool bSub, double fVal, svl::SharedString aString, ScMatrix& rMat)
+void ScMatrix::PowOp(bool bFlag, svl::SharedString aString, double fVal, ScMatrix& rMat)
 {
-    if(bSub)
+    if (bFlag)
     {
-        SubOp aOp(fVal, aString);
+        auto pow_ = [&](double a, double b){return pow(b, a);};
+        matop::MatOp<decltype(pow_)> aOp(pow_, aString, fVal);
         pImpl->ApplyOperation(aOp, *rMat.pImpl);
     }
     else
     {
-        AddOp aOp(fVal, aString);
+        auto pow_ = [&](double a, double b){return pow(a, b);};
+        matop::MatOp<decltype(pow_)> aOp(pow_, aString, fVal);
         pImpl->ApplyOperation(aOp, *rMat.pImpl);
     }
 }


More information about the Libreoffice-commits mailing list