b6b6a13
From afe38c9b2b958f8b1c0c79c91bfc002b88f34e37 Mon Sep 17 00:00:00 2001
b6b6a13
Message-Id: <afe38c9b2b958f8b1c0c79c91bfc002b88f34e37.1418323726.git.erack@redhat.com>
b6b6a13
From: Eike Rathke <erack@redhat.com>
b6b6a13
Date: Thu, 11 Dec 2014 16:39:58 +0100
b6b6a13
Subject: [PATCH] resolved fdo#87237 propagate error values through matrix
b6b6a13
 comparisons
b6b6a13
MIME-Version: 1.0
b6b6a13
Content-Type: multipart/mixed; boundary="------------erAck-patch-parts"
b6b6a13
b6b6a13
This is a multi-part message in MIME format.
b6b6a13
--------------erAck-patch-parts
b6b6a13
Content-Type: text/plain; charset=UTF-8; format=fixed
b6b6a13
Content-Transfer-Encoding: 8bit
b6b6a13
b6b6a13
b6b6a13
Apparently introduced with 8e8b43a03e77dd251876c1de0ac06eeeb09192cd the
b6b6a13
comparison results were stored as boolean values, effectively discarding
b6b6a13
any infinite double values and error values encoded as NaN values.
b6b6a13
b6b6a13
(cherry picked from commit 3c405ff82fcc9f8f044833420485c54658064636)
b6b6a13
b6b6a13
Change-Id: I1fb6f46894a0bee02a37e28b7e6cc84f8c051f28
b6b6a13
---
b6b6a13
 sc/inc/scmatrix.hxx              |  2 +-
b6b6a13
 sc/source/core/tool/scmatrix.cxx | 96 ++++++++++++++++++++++------------------
b6b6a13
 2 files changed, 53 insertions(+), 45 deletions(-)
b6b6a13
b6b6a13
b6b6a13
--------------erAck-patch-parts
b6b6a13
Content-Type: text/x-patch; name="0001-resolved-fdo-87237-propagate-error-values-through-ma.patch"
b6b6a13
Content-Transfer-Encoding: 8bit
b6b6a13
Content-Disposition: attachment; filename="0001-resolved-fdo-87237-propagate-error-values-through-ma.patch"
b6b6a13
b6b6a13
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
b6b6a13
index 1db1641..0833c4d 100644
b6b6a13
--- a/sc/inc/scmatrix.hxx
b6b6a13
+++ b/sc/inc/scmatrix.hxx
b6b6a13
@@ -202,7 +202,7 @@ public:
b6b6a13
     ScMatrix(SCSIZE nC, SCSIZE nR);
b6b6a13
     ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal);
b6b6a13
 
b6b6a13
-    ScMatrix( size_t nC, size_t nR, const std::vector<bool>& rInitVals );
b6b6a13
+    ScMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals );
b6b6a13
 
b6b6a13
     /** Clone the matrix. */
b6b6a13
     ScMatrix* Clone() const;
b6b6a13
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
b6b6a13
index 4f210a8..2e31ec8 100644
b6b6a13
--- a/sc/source/core/tool/scmatrix.cxx
b6b6a13
+++ b/sc/source/core/tool/scmatrix.cxx
b6b6a13
@@ -69,51 +69,63 @@ typedef mdds::multi_type_matrix<custom_string_trait> MatrixImplType;
b6b6a13
 
b6b6a13
 namespace {
b6b6a13
 
b6b6a13
-struct ElemEqualZero : public unary_function<double, bool>
b6b6a13
+struct ElemEqualZero : public unary_function<double, double>
b6b6a13
 {
b6b6a13
-    bool operator() (double val) const
b6b6a13
+    double operator() (double val) const
b6b6a13
     {
b6b6a13
-        return val == 0.0;
b6b6a13
+        if (!::rtl::math::isFinite(val))
b6b6a13
+            return val;
b6b6a13
+        return val == 0.0 ? 1.0 : 0.0;
b6b6a13
     }
b6b6a13
 };
b6b6a13
 
b6b6a13
-struct ElemNotEqualZero : public unary_function<double, bool>
b6b6a13
+struct ElemNotEqualZero : public unary_function<double, double>
b6b6a13
 {
b6b6a13
-    bool operator() (double val) const
b6b6a13
+    double operator() (double val) const
b6b6a13
     {
b6b6a13
-        return val != 0.0;
b6b6a13
+        if (!::rtl::math::isFinite(val))
b6b6a13
+            return val;
b6b6a13
+        return val != 0.0 ? 1.0 : 0.0;
b6b6a13
     }
b6b6a13
 };
b6b6a13
 
b6b6a13
-struct ElemGreaterZero : public unary_function<double, bool>
b6b6a13
+struct ElemGreaterZero : public unary_function<double, double>
b6b6a13
 {
b6b6a13
-    bool operator() (double val) const
b6b6a13
+    double operator() (double val) const
b6b6a13
     {
b6b6a13
-        return val > 0.0;
b6b6a13
+        if (!::rtl::math::isFinite(val))
b6b6a13
+            return val;
b6b6a13
+        return val > 0.0 ? 1.0 : 0.0;
b6b6a13
     }
b6b6a13
 };
b6b6a13
 
b6b6a13
-struct ElemLessZero : public unary_function<double, bool>
b6b6a13
+struct ElemLessZero : public unary_function<double, double>
b6b6a13
 {
b6b6a13
-    bool operator() (double val) const
b6b6a13
+    double operator() (double val) const
b6b6a13
     {
b6b6a13
-        return val < 0.0;
b6b6a13
+        if (!::rtl::math::isFinite(val))
b6b6a13
+            return val;
b6b6a13
+        return val < 0.0 ? 1.0 : 0.0;
b6b6a13
     }
b6b6a13
 };
b6b6a13
 
b6b6a13
-struct ElemGreaterEqualZero : public unary_function<double, bool>
b6b6a13
+struct ElemGreaterEqualZero : public unary_function<double, double>
b6b6a13
 {
b6b6a13
-    bool operator() (double val) const
b6b6a13
+    double operator() (double val) const
b6b6a13
     {
b6b6a13
-        return val >= 0.0;
b6b6a13
+        if (!::rtl::math::isFinite(val))
b6b6a13
+            return val;
b6b6a13
+        return val >= 0.0 ? 1.0 : 0.0;
b6b6a13
     }
b6b6a13
 };
b6b6a13
 
b6b6a13
-struct ElemLessEqualZero : public unary_function<double, bool>
b6b6a13
+struct ElemLessEqualZero : public unary_function<double, double>
b6b6a13
 {
b6b6a13
-    bool operator() (double val) const
b6b6a13
+    double operator() (double val) const
b6b6a13
     {
b6b6a13
-        return val <= 0.0;
b6b6a13
+        if (!::rtl::math::isFinite(val))
b6b6a13
+            return val;
b6b6a13
+        return val <= 0.0 ? 1.0 : 0.0;
b6b6a13
     }
b6b6a13
 };
b6b6a13
 
b6b6a13
@@ -122,7 +134,7 @@ class CompareMatrixElemFunc : std::unary_function
b6b6a13
 {
b6b6a13
     static _Comp maComp;
b6b6a13
 
b6b6a13
-    std::vector<bool> maNewMatValues;
b6b6a13
+    std::vector<double> maNewMatValues;     // double instead of bool to transport error values
b6b6a13
     size_t mnRow;
b6b6a13
     size_t mnCol;
b6b6a13
 public:
b6b6a13
@@ -144,13 +156,6 @@ public:
b6b6a13
                 for (; it != itEnd; ++it)
b6b6a13
                 {
b6b6a13
                     double fVal = *it;
b6b6a13
-                    if (!rtl::math::isFinite(fVal))
b6b6a13
-                    {
b6b6a13
-                        /* FIXME: this silently skips an error instead of propagating it! */
b6b6a13
-                        maNewMatValues.push_back(false);
b6b6a13
-                        continue;
b6b6a13
-                    }
b6b6a13
-
b6b6a13
                     maNewMatValues.push_back(maComp(fVal));
b6b6a13
                 }
b6b6a13
             }
b6b6a13
@@ -172,7 +177,7 @@ public:
b6b6a13
             case mdds::mtm::element_empty:
b6b6a13
             default:
b6b6a13
                 // Fill it with false.
b6b6a13
-                maNewMatValues.resize(maNewMatValues.size() + node.size, false);
b6b6a13
+                maNewMatValues.resize(maNewMatValues.size() + node.size, 0.0);
b6b6a13
         }
b6b6a13
     }
b6b6a13
 
b6b6a13
@@ -201,7 +206,7 @@ public:
b6b6a13
     ScMatrixImpl(SCSIZE nC, SCSIZE nR);
b6b6a13
     ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal);
b6b6a13
 
b6b6a13
-    ScMatrixImpl( size_t nC, size_t nR, const std::vector<bool>& rInitVals );
b6b6a13
+    ScMatrixImpl( size_t nC, size_t nR, const std::vector<double>& rInitVals );
b6b6a13
 
b6b6a13
     ~ScMatrixImpl();
b6b6a13
 
b6b6a13
@@ -296,7 +301,7 @@ ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR) :
b6b6a13
 ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal) :
b6b6a13
     maMat(nR, nC, fInitVal), maMatFlag(nR, nC), pErrorInterpreter(NULL), mbCloneIfConst(true) {}
b6b6a13
 
b6b6a13
-ScMatrixImpl::ScMatrixImpl( size_t nC, size_t nR, const std::vector<bool>& rInitVals ) :
b6b6a13
+ScMatrixImpl::ScMatrixImpl( size_t nC, size_t nR, const std::vector<double>& rInitVals ) :
b6b6a13
     maMat(nR, nC, rInitVals.begin(), rInitVals.end()), maMatFlag(nR, nC), pErrorInterpreter(NULL), mbCloneIfConst(true) {}
b6b6a13
 
b6b6a13
 ScMatrixImpl::~ScMatrixImpl()
b6b6a13
@@ -1290,32 +1295,35 @@ public:
b6b6a13
     }
b6b6a13
 };
b6b6a13
 
b6b6a13
-inline bool evaluate( double fVal, ScQueryOp eOp )
b6b6a13
+inline double evaluate( double fVal, ScQueryOp eOp )
b6b6a13
 {
b6b6a13
+    if (!rtl::math::isFinite(fVal))
b6b6a13
+        return fVal;
b6b6a13
+
b6b6a13
     switch (eOp)
b6b6a13
     {
b6b6a13
         case SC_EQUAL:
b6b6a13
-            return fVal == 0.0;
b6b6a13
+            return fVal == 0.0 ? 1.0 : 0.0;
b6b6a13
         case SC_LESS:
b6b6a13
-            return fVal < 0.0;
b6b6a13
+            return fVal < 0.0 ? 1.0 : 0.0;
b6b6a13
         case SC_GREATER:
b6b6a13
-            return fVal > 0.0;
b6b6a13
+            return fVal > 0.0 ? 1.0 : 0.0;
b6b6a13
         break;
b6b6a13
         case SC_LESS_EQUAL:
b6b6a13
-            return fVal <= 0.0;
b6b6a13
+            return fVal <= 0.0 ? 1.0 : 0.0;
b6b6a13
         break;
b6b6a13
         case SC_GREATER_EQUAL:
b6b6a13
-            return fVal >= 0.0;
b6b6a13
+            return fVal >= 0.0 ? 1.0 : 0.0;
b6b6a13
         break;
b6b6a13
         case SC_NOT_EQUAL:
b6b6a13
-            return fVal != 0.0;
b6b6a13
+            return fVal != 0.0 ? 1.0 : 0.0;
b6b6a13
         break;
b6b6a13
         default:
b6b6a13
             ;
b6b6a13
     }
b6b6a13
 
b6b6a13
     OSL_TRACE( "evaluate: unhandled comparison operator: %d", (int)eOp);
b6b6a13
-    return false;
b6b6a13
+    return CreateDoubleError( errUnknownState);
b6b6a13
 }
b6b6a13
 
b6b6a13
 class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type, void>
b6b6a13
@@ -1323,7 +1331,7 @@ class CompareMatrixFunc : std::unary_function
b6b6a13
     sc::Compare& mrComp;
b6b6a13
     size_t mnMatPos;
b6b6a13
     sc::CompareOptions* mpOptions;
b6b6a13
-    std::vector<bool> maResValues;
b6b6a13
+    std::vector<double> maResValues;    // double instead of bool to transport error values
b6b6a13
 
b6b6a13
     void compare()
b6b6a13
     {
b6b6a13
@@ -1403,7 +1411,7 @@ public:
b6b6a13
         }
b6b6a13
     }
b6b6a13
 
b6b6a13
-    const std::vector<bool>& getValues() const
b6b6a13
+    const std::vector<double>& getValues() const
b6b6a13
     {
b6b6a13
         return maResValues;
b6b6a13
     }
b6b6a13
@@ -1417,7 +1425,7 @@ class CompareMatrixToNumericFunc : std::unary_function
b6b6a13
     sc::Compare& mrComp;
b6b6a13
     double mfRightValue;
b6b6a13
     sc::CompareOptions* mpOptions;
b6b6a13
-    std::vector<bool> maResValues;
b6b6a13
+    std::vector<double> maResValues;    // double instead of bool to transport error values
b6b6a13
 
b6b6a13
     void compare()
b6b6a13
     {
b6b6a13
@@ -1495,7 +1503,7 @@ public:
b6b6a13
         }
b6b6a13
     }
b6b6a13
 
b6b6a13
-    const std::vector<bool>& getValues() const
b6b6a13
+    const std::vector<double>& getValues() const
b6b6a13
     {
b6b6a13
         return maResValues;
b6b6a13
     }
b6b6a13
@@ -1717,7 +1725,7 @@ ScMatrixRef ScMatrixImpl::CompareMatrix(
b6b6a13
             maMat.walk(aFunc);
b6b6a13
 
b6b6a13
             // We assume the result matrix has the same dimension as this matrix.
b6b6a13
-            const std::vector<bool>& rResVal = aFunc.getValues();
b6b6a13
+            const std::vector<double>& rResVal = aFunc.getValues();
b6b6a13
             if (nSize != rResVal.size())
b6b6a13
                 ScMatrixRef();
b6b6a13
 
b6b6a13
@@ -1729,7 +1737,7 @@ ScMatrixRef ScMatrixImpl::CompareMatrix(
b6b6a13
     maMat.walk(aFunc);
b6b6a13
 
b6b6a13
     // We assume the result matrix has the same dimension as this matrix.
b6b6a13
-    const std::vector<bool>& rResVal = aFunc.getValues();
b6b6a13
+    const std::vector<double>& rResVal = aFunc.getValues();
b6b6a13
     if (nSize != rResVal.size())
b6b6a13
         ScMatrixRef();
b6b6a13
 
b6b6a13
@@ -1888,7 +1896,7 @@ ScMatrix::ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal) :
b6b6a13
     SAL_WARN_IF( !nR, "sc", "ScMatrix with 0 rows!");
b6b6a13
 }
b6b6a13
 
b6b6a13
-ScMatrix::ScMatrix( size_t nC, size_t nR, const std::vector<bool>& rInitVals ) :
b6b6a13
+ScMatrix::ScMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals ) :
b6b6a13
     pImpl(new ScMatrixImpl(nC, nR, rInitVals)), nRefCnt(0)
b6b6a13
 {
b6b6a13
     SAL_WARN_IF( !nC, "sc", "ScMatrix with 0 columns!");
b6b6a13
b6b6a13
--------------erAck-patch-parts--
b6b6a13
b6b6a13