Blob Blame History Raw
From afe38c9b2b958f8b1c0c79c91bfc002b88f34e37 Mon Sep 17 00:00:00 2001
Message-Id: <afe38c9b2b958f8b1c0c79c91bfc002b88f34e37.1418323726.git.erack@redhat.com>
From: Eike Rathke <erack@redhat.com>
Date: Thu, 11 Dec 2014 16:39:58 +0100
Subject: [PATCH] resolved fdo#87237 propagate error values through matrix
 comparisons
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------erAck-patch-parts"

This is a multi-part message in MIME format.
--------------erAck-patch-parts
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit


Apparently introduced with 8e8b43a03e77dd251876c1de0ac06eeeb09192cd the
comparison results were stored as boolean values, effectively discarding
any infinite double values and error values encoded as NaN values.

(cherry picked from commit 3c405ff82fcc9f8f044833420485c54658064636)

Change-Id: I1fb6f46894a0bee02a37e28b7e6cc84f8c051f28
---
 sc/inc/scmatrix.hxx              |  2 +-
 sc/source/core/tool/scmatrix.cxx | 96 ++++++++++++++++++++++------------------
 2 files changed, 53 insertions(+), 45 deletions(-)


--------------erAck-patch-parts
Content-Type: text/x-patch; name="0001-resolved-fdo-87237-propagate-error-values-through-ma.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0001-resolved-fdo-87237-propagate-error-values-through-ma.patch"

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 1db1641..0833c4d 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -202,7 +202,7 @@ public:
     ScMatrix(SCSIZE nC, SCSIZE nR);
     ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal);
 
-    ScMatrix( size_t nC, size_t nR, const std::vector<bool>& rInitVals );
+    ScMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals );
 
     /** Clone the matrix. */
     ScMatrix* Clone() const;
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 4f210a8..2e31ec8 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -69,51 +69,63 @@ typedef mdds::multi_type_matrix<custom_string_trait> MatrixImplType;
 
 namespace {
 
-struct ElemEqualZero : public unary_function<double, bool>
+struct ElemEqualZero : public unary_function<double, double>
 {
-    bool operator() (double val) const
+    double operator() (double val) const
     {
-        return val == 0.0;
+        if (!::rtl::math::isFinite(val))
+            return val;
+        return val == 0.0 ? 1.0 : 0.0;
     }
 };
 
-struct ElemNotEqualZero : public unary_function<double, bool>
+struct ElemNotEqualZero : public unary_function<double, double>
 {
-    bool operator() (double val) const
+    double operator() (double val) const
     {
-        return val != 0.0;
+        if (!::rtl::math::isFinite(val))
+            return val;
+        return val != 0.0 ? 1.0 : 0.0;
     }
 };
 
-struct ElemGreaterZero : public unary_function<double, bool>
+struct ElemGreaterZero : public unary_function<double, double>
 {
-    bool operator() (double val) const
+    double operator() (double val) const
     {
-        return val > 0.0;
+        if (!::rtl::math::isFinite(val))
+            return val;
+        return val > 0.0 ? 1.0 : 0.0;
     }
 };
 
-struct ElemLessZero : public unary_function<double, bool>
+struct ElemLessZero : public unary_function<double, double>
 {
-    bool operator() (double val) const
+    double operator() (double val) const
     {
-        return val < 0.0;
+        if (!::rtl::math::isFinite(val))
+            return val;
+        return val < 0.0 ? 1.0 : 0.0;
     }
 };
 
-struct ElemGreaterEqualZero : public unary_function<double, bool>
+struct ElemGreaterEqualZero : public unary_function<double, double>
 {
-    bool operator() (double val) const
+    double operator() (double val) const
     {
-        return val >= 0.0;
+        if (!::rtl::math::isFinite(val))
+            return val;
+        return val >= 0.0 ? 1.0 : 0.0;
     }
 };
 
-struct ElemLessEqualZero : public unary_function<double, bool>
+struct ElemLessEqualZero : public unary_function<double, double>
 {
-    bool operator() (double val) const
+    double operator() (double val) const
     {
-        return val <= 0.0;
+        if (!::rtl::math::isFinite(val))
+            return val;
+        return val <= 0.0 ? 1.0 : 0.0;
     }
 };
 
@@ -122,7 +134,7 @@ class CompareMatrixElemFunc : std::unary_function<MatrixImplType::element_block_
 {
     static _Comp maComp;
 
-    std::vector<bool> maNewMatValues;
+    std::vector<double> maNewMatValues;     // double instead of bool to transport error values
     size_t mnRow;
     size_t mnCol;
 public:
@@ -144,13 +156,6 @@ public:
                 for (; it != itEnd; ++it)
                 {
                     double fVal = *it;
-                    if (!rtl::math::isFinite(fVal))
-                    {
-                        /* FIXME: this silently skips an error instead of propagating it! */
-                        maNewMatValues.push_back(false);
-                        continue;
-                    }
-
                     maNewMatValues.push_back(maComp(fVal));
                 }
             }
@@ -172,7 +177,7 @@ public:
             case mdds::mtm::element_empty:
             default:
                 // Fill it with false.
-                maNewMatValues.resize(maNewMatValues.size() + node.size, false);
+                maNewMatValues.resize(maNewMatValues.size() + node.size, 0.0);
         }
     }
 
@@ -201,7 +206,7 @@ public:
     ScMatrixImpl(SCSIZE nC, SCSIZE nR);
     ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal);
 
-    ScMatrixImpl( size_t nC, size_t nR, const std::vector<bool>& rInitVals );
+    ScMatrixImpl( size_t nC, size_t nR, const std::vector<double>& rInitVals );
 
     ~ScMatrixImpl();
 
@@ -296,7 +301,7 @@ ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR) :
 ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal) :
     maMat(nR, nC, fInitVal), maMatFlag(nR, nC), pErrorInterpreter(NULL), mbCloneIfConst(true) {}
 
-ScMatrixImpl::ScMatrixImpl( size_t nC, size_t nR, const std::vector<bool>& rInitVals ) :
+ScMatrixImpl::ScMatrixImpl( size_t nC, size_t nR, const std::vector<double>& rInitVals ) :
     maMat(nR, nC, rInitVals.begin(), rInitVals.end()), maMatFlag(nR, nC), pErrorInterpreter(NULL), mbCloneIfConst(true) {}
 
 ScMatrixImpl::~ScMatrixImpl()
@@ -1290,32 +1295,35 @@ public:
     }
 };
 
-inline bool evaluate( double fVal, ScQueryOp eOp )
+inline double evaluate( double fVal, ScQueryOp eOp )
 {
+    if (!rtl::math::isFinite(fVal))
+        return fVal;
+
     switch (eOp)
     {
         case SC_EQUAL:
-            return fVal == 0.0;
+            return fVal == 0.0 ? 1.0 : 0.0;
         case SC_LESS:
-            return fVal < 0.0;
+            return fVal < 0.0 ? 1.0 : 0.0;
         case SC_GREATER:
-            return fVal > 0.0;
+            return fVal > 0.0 ? 1.0 : 0.0;
         break;
         case SC_LESS_EQUAL:
-            return fVal <= 0.0;
+            return fVal <= 0.0 ? 1.0 : 0.0;
         break;
         case SC_GREATER_EQUAL:
-            return fVal >= 0.0;
+            return fVal >= 0.0 ? 1.0 : 0.0;
         break;
         case SC_NOT_EQUAL:
-            return fVal != 0.0;
+            return fVal != 0.0 ? 1.0 : 0.0;
         break;
         default:
             ;
     }
 
     OSL_TRACE( "evaluate: unhandled comparison operator: %d", (int)eOp);
-    return false;
+    return CreateDoubleError( errUnknownState);
 }
 
 class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type, void>
@@ -1323,7 +1331,7 @@ class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type
     sc::Compare& mrComp;
     size_t mnMatPos;
     sc::CompareOptions* mpOptions;
-    std::vector<bool> maResValues;
+    std::vector<double> maResValues;    // double instead of bool to transport error values
 
     void compare()
     {
@@ -1403,7 +1411,7 @@ public:
         }
     }
 
-    const std::vector<bool>& getValues() const
+    const std::vector<double>& getValues() const
     {
         return maResValues;
     }
@@ -1417,7 +1425,7 @@ class CompareMatrixToNumericFunc : std::unary_function<MatrixImplType::element_b
     sc::Compare& mrComp;
     double mfRightValue;
     sc::CompareOptions* mpOptions;
-    std::vector<bool> maResValues;
+    std::vector<double> maResValues;    // double instead of bool to transport error values
 
     void compare()
     {
@@ -1495,7 +1503,7 @@ public:
         }
     }
 
-    const std::vector<bool>& getValues() const
+    const std::vector<double>& getValues() const
     {
         return maResValues;
     }
@@ -1717,7 +1725,7 @@ ScMatrixRef ScMatrixImpl::CompareMatrix(
             maMat.walk(aFunc);
 
             // We assume the result matrix has the same dimension as this matrix.
-            const std::vector<bool>& rResVal = aFunc.getValues();
+            const std::vector<double>& rResVal = aFunc.getValues();
             if (nSize != rResVal.size())
                 ScMatrixRef();
 
@@ -1729,7 +1737,7 @@ ScMatrixRef ScMatrixImpl::CompareMatrix(
     maMat.walk(aFunc);
 
     // We assume the result matrix has the same dimension as this matrix.
-    const std::vector<bool>& rResVal = aFunc.getValues();
+    const std::vector<double>& rResVal = aFunc.getValues();
     if (nSize != rResVal.size())
         ScMatrixRef();
 
@@ -1888,7 +1896,7 @@ ScMatrix::ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal) :
     SAL_WARN_IF( !nR, "sc", "ScMatrix with 0 rows!");
 }
 
-ScMatrix::ScMatrix( size_t nC, size_t nR, const std::vector<bool>& rInitVals ) :
+ScMatrix::ScMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals ) :
     pImpl(new ScMatrixImpl(nC, nR, rInitVals)), nRefCnt(0)
 {
     SAL_WARN_IF( !nC, "sc", "ScMatrix with 0 columns!");

--------------erAck-patch-parts--