LCOV - code coverage report
Current view: top level - sc/source/core/tool - scmatrix.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 318 555 57.3 %
Date: 2012-08-25 Functions: 100 172 58.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 135 468 28.8 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include "scmatrix.hxx"
      31                 :            : #include "global.hxx"
      32                 :            : #include "address.hxx"
      33                 :            : #include "formula/errorcodes.hxx"
      34                 :            : #include "interpre.hxx"
      35                 :            : #include <svl/zforlist.hxx>
      36                 :            : #include <tools/stream.hxx>
      37                 :            : #include <rtl/math.hxx>
      38                 :            : 
      39                 :            : #include <math.h>
      40                 :            : 
      41                 :            : #include <vector>
      42                 :            : 
      43                 :            : #include <mdds/multi_type_matrix.hpp>
      44                 :            : #include <mdds/multi_type_vector_types.hpp>
      45                 :            : #include <mdds/multi_type_vector_trait.hpp>
      46                 :            : 
      47                 :            : using ::std::pair;
      48                 :            : using ::std::for_each;
      49                 :            : using ::std::count_if;
      50                 :            : using ::std::advance;
      51                 :            : using ::std::unary_function;
      52                 :            : 
      53                 :            : const mdds::mtv::element_t element_type_custom_string = mdds::mtv::element_type_user_start;
      54                 :            : typedef mdds::mtv::default_element_block<element_type_custom_string, rtl::OUString> custom_string_block;
      55                 :            : 
      56                 :            : namespace rtl {
      57                 :            : 
      58                 :            : // Callback functions required for supporting rtl::OUString in
      59                 :            : // mdds::multi_type_vector.  They must be in the rtl namespace to satisfy
      60                 :            : // argument dependent lookup that mdds::multi_type_vector requires.
      61                 :        201 : MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(OUString, element_type_custom_string, OUString(), custom_string_block)
      62                 :            : 
      63                 :            : }
      64                 :            : 
      65                 :            : /**
      66                 :            :  * Custom string trait struct to tell mdds::multi_type_matrix about the
      67                 :            :  * custom string type and how to handle blocks storing them.
      68                 :            :  */
      69                 :            : struct custom_string_trait
      70                 :            : {
      71                 :            :     typedef OUString string_type;
      72                 :            :     typedef custom_string_block string_element_block;
      73                 :            : 
      74                 :            :     static const mdds::mtv::element_t string_type_identifier = element_type_custom_string;
      75                 :            : 
      76                 :            :     struct element_block_func
      77                 :            :     {
      78                 :         82 :         static mdds::mtv::base_element_block* create_new_block(
      79                 :            :             mdds::mtv::element_t type, size_t init_size)
      80                 :            :         {
      81         [ +  + ]:         82 :             switch (type)
      82                 :            :             {
      83                 :            :                 case element_type_custom_string:
      84                 :         36 :                     return string_element_block::create_block(init_size);
      85                 :            :                 default:
      86                 :         82 :                     return mdds::mtv::element_block_func::create_new_block(type, init_size);
      87                 :            :             }
      88                 :            :         }
      89                 :            : 
      90                 :          0 :         static mdds::mtv::base_element_block* clone_block(const mdds::mtv::base_element_block& block)
      91                 :            :         {
      92         [ #  # ]:          0 :             switch (mdds::mtv::get_block_type(block))
      93                 :            :             {
      94                 :            :                 case element_type_custom_string:
      95                 :          0 :                     return string_element_block::clone_block(block);
      96                 :            :                 default:
      97                 :          0 :                     return mdds::mtv::element_block_func::clone_block(block);
      98                 :            :             }
      99                 :            :         }
     100                 :            : 
     101                 :        700 :         static void delete_block(mdds::mtv::base_element_block* p)
     102                 :            :         {
     103         [ +  + ]:        700 :             if (!p)
     104                 :        700 :                 return;
     105                 :            : 
     106         [ +  + ]:        371 :             switch (mdds::mtv::get_block_type(*p))
     107                 :            :             {
     108                 :            :                 case element_type_custom_string:
     109                 :         45 :                     string_element_block::delete_block(p);
     110                 :         45 :                 break;
     111                 :            :                 default:
     112                 :        326 :                     mdds::mtv::element_block_func::delete_block(p);
     113                 :            :             }
     114                 :            :         }
     115                 :            : 
     116                 :          6 :         static void resize_block(mdds::mtv::base_element_block& block, size_t new_size)
     117                 :            :         {
     118         [ -  + ]:          6 :             switch (mdds::mtv::get_block_type(block))
     119                 :            :             {
     120                 :            :                 case element_type_custom_string:
     121                 :          0 :                     string_element_block::resize_block(block, new_size);
     122                 :          0 :                 break;
     123                 :            :                 default:
     124                 :          6 :                     mdds::mtv::element_block_func::resize_block(block, new_size);
     125                 :            :             }
     126                 :          6 :         }
     127                 :            : 
     128                 :            :         static void print_block(const mdds::mtv::base_element_block& block)
     129                 :            :         {
     130                 :            :             switch (mdds::mtv::get_block_type(block))
     131                 :            :             {
     132                 :            :                 case element_type_custom_string:
     133                 :            :                     string_element_block::print_block(block);
     134                 :            :                 break;
     135                 :            :                 default:
     136                 :            :                     mdds::mtv::element_block_func::print_block(block);
     137                 :            :             }
     138                 :            :         }
     139                 :            : 
     140                 :          6 :         static void erase(mdds::mtv::base_element_block& block, size_t pos)
     141                 :            :         {
     142         [ -  + ]:          6 :             switch (mdds::mtv::get_block_type(block))
     143                 :            :             {
     144                 :            :                 case element_type_custom_string:
     145                 :          0 :                     string_element_block::erase_block(block, pos);
     146                 :          0 :                 break;
     147                 :            :                 default:
     148                 :          6 :                     mdds::mtv::element_block_func::erase(block, pos);
     149                 :            :             }
     150                 :          6 :         }
     151                 :            : 
     152                 :          0 :         static void erase(mdds::mtv::base_element_block& block, size_t pos, size_t size)
     153                 :            :         {
     154         [ #  # ]:          0 :             switch (mdds::mtv::get_block_type(block))
     155                 :            :             {
     156                 :            :                 case element_type_custom_string:
     157                 :          0 :                     string_element_block::erase_block(block, pos, size);
     158                 :          0 :                 break;
     159                 :            :                 default:
     160                 :          0 :                     mdds::mtv::element_block_func::erase(block, pos, size);
     161                 :            :             }
     162                 :          0 :         }
     163                 :            : 
     164                 :          6 :         static void append_values_from_block(
     165                 :            :             mdds::mtv::base_element_block& dest, const mdds::mtv::base_element_block& src)
     166                 :            :         {
     167         [ -  + ]:          6 :             switch (mdds::mtv::get_block_type(dest))
     168                 :            :             {
     169                 :            :                 case element_type_custom_string:
     170                 :          0 :                     string_element_block::append_values_from_block(dest, src);
     171                 :          0 :                 break;
     172                 :            :                 default:
     173                 :          6 :                     mdds::mtv::element_block_func::append_values_from_block(dest, src);
     174                 :            :             }
     175                 :          6 :         }
     176                 :            : 
     177                 :          0 :         static void append_values_from_block(
     178                 :            :             mdds::mtv::base_element_block& dest, const mdds::mtv::base_element_block& src,
     179                 :            :             size_t begin_pos, size_t len)
     180                 :            :         {
     181         [ #  # ]:          0 :             switch (mdds::mtv::get_block_type(dest))
     182                 :            :             {
     183                 :            :                 case element_type_custom_string:
     184                 :          0 :                     string_element_block::append_values_from_block(dest, src, begin_pos, len);
     185                 :          0 :                 break;
     186                 :            :                 default:
     187                 :          0 :                     mdds::mtv::element_block_func::append_values_from_block(dest, src, begin_pos, len);
     188                 :            :             }
     189                 :          0 :         }
     190                 :            : 
     191                 :          0 :         static void assign_values_from_block(
     192                 :            :             mdds::mtv::base_element_block& dest, const mdds::mtv::base_element_block& src,
     193                 :            :             size_t begin_pos, size_t len)
     194                 :            :         {
     195         [ #  # ]:          0 :             switch (mdds::mtv::get_block_type(dest))
     196                 :            :             {
     197                 :            :                 case element_type_custom_string:
     198                 :          0 :                     string_element_block::assign_values_from_block(dest, src, begin_pos, len);
     199                 :          0 :                 break;
     200                 :            :                 default:
     201                 :          0 :                     mdds::mtv::element_block_func::assign_values_from_block(dest, src, begin_pos, len);
     202                 :            :             }
     203                 :          0 :         }
     204                 :            : 
     205                 :            :         static bool equal_block(
     206                 :            :             const mdds::mtv::base_element_block& left, const mdds::mtv::base_element_block& right)
     207                 :            :         {
     208                 :            :             if (mdds::mtv::get_block_type(left) == element_type_custom_string)
     209                 :            :             {
     210                 :            :                 if (mdds::mtv::get_block_type(right) != element_type_custom_string)
     211                 :            :                     return false;
     212                 :            : 
     213                 :            :                 return string_element_block::get(left) == string_element_block::get(right);
     214                 :            :             }
     215                 :            :             else if (mdds::mtv::get_block_type(right) == element_type_custom_string)
     216                 :            :                 return false;
     217                 :            : 
     218                 :            :             return mdds::mtv::element_block_func::equal_block(left, right);
     219                 :            :         }
     220                 :            : 
     221                 :        709 :         static void overwrite_values(mdds::mtv::base_element_block& block, size_t pos, size_t len)
     222                 :            :         {
     223         [ -  + ]:        709 :             switch (mdds::mtv::get_block_type(block))
     224                 :            :             {
     225                 :            :                 case element_type_custom_string:
     226                 :            :                     // Do nothing.  One needs to handle this only when the
     227                 :            :                     // block stores pointers and manages their life cycles.
     228                 :          0 :                 break;
     229                 :            :                 default:
     230                 :        709 :                     mdds::mtv::element_block_func::overwrite_values(block, pos, len);
     231                 :            :             }
     232                 :        709 :         }
     233                 :            :     };
     234                 :            : };
     235                 :            : 
     236                 :            : // ============================================================================
     237                 :            : 
     238                 :            : namespace {
     239                 :            : 
     240                 :            : typedef mdds::multi_type_matrix<custom_string_trait> MatrixImplType;
     241                 :            : 
     242                 :            : struct ElemEqualZero : public unary_function<double, bool>
     243                 :            : {
     244                 :        192 :     bool operator() (double val) const
     245                 :            :     {
     246                 :        192 :         return val == 0.0;
     247                 :            :     }
     248                 :            : };
     249                 :            : 
     250                 :            : struct ElemNotEqualZero : public unary_function<double, bool>
     251                 :            : {
     252                 :          0 :     bool operator() (double val) const
     253                 :            :     {
     254                 :          0 :         return val != 0.0;
     255                 :            :     }
     256                 :            : };
     257                 :            : 
     258                 :            : struct ElemGreaterZero : public unary_function<double, bool>
     259                 :            : {
     260                 :          0 :     bool operator() (double val) const
     261                 :            :     {
     262                 :          0 :         return val > 0.0;
     263                 :            :     }
     264                 :            : };
     265                 :            : 
     266                 :            : struct ElemLessZero : public unary_function<double, bool>
     267                 :            : {
     268                 :          0 :     bool operator() (double val) const
     269                 :            :     {
     270                 :          0 :         return val < 0.0;
     271                 :            :     }
     272                 :            : };
     273                 :            : 
     274                 :            : struct ElemGreaterEqualZero : public unary_function<double, bool>
     275                 :            : {
     276                 :          0 :     bool operator() (double val) const
     277                 :            :     {
     278                 :          0 :         return val >= 0.0;
     279                 :            :     }
     280                 :            : };
     281                 :            : 
     282                 :            : struct ElemLessEqualZero : public unary_function<double, bool>
     283                 :            : {
     284                 :          0 :     bool operator() (double val) const
     285                 :            :     {
     286                 :          0 :         return val <= 0.0;
     287                 :            :     }
     288                 :            : };
     289                 :            : 
     290                 :            : template<typename _Comp>
     291                 :         72 : void compareMatrix(MatrixImplType& rMat)
     292                 :            : {
     293                 :         72 :     MatrixImplType::size_pair_type aDim = rMat.size();
     294   [ #  #  #  #  :         72 :     MatrixImplType aNewMat(aDim.row, aDim.column, false); // initialize with boolean block.  faster this way.
          #  #  #  #  #  
                #  +  - ]
     295                 :            : 
     296                 :            :     _Comp aComp;
     297 [ #  # ][ #  # ]:        264 :     for (size_t i = 0; i < aDim.row; ++i)
         [ #  # ][ #  # ]
         [ #  # ][ +  + ]
     298                 :            :     {
     299 [ #  # ][ #  # ]:        384 :         for (size_t j = 0; j < aDim.column; ++j)
         [ #  # ][ #  # ]
         [ #  # ][ +  + ]
     300                 :            :         {
     301 [ #  # ][ #  # ]:        192 :             mdds::mtm::element_t eType = rMat.get_type(i, j);
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
     302 [ #  # ][ #  # ]:        192 :             if (eType != mdds::mtm::element_numeric && eType != mdds::mtm::element_boolean)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ #  # ]
     303                 :            :                 // must be of numeric type (boolean can be numeric).
     304                 :          0 :                 continue;
     305                 :            : 
     306 [ #  # ][ #  # ]:        192 :             double fVal = rMat.get_numeric(i, j);
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
     307 [ #  # ][ #  # ]:        192 :             if (!::rtl::math::isFinite(fVal))
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     308                 :          0 :                 continue;
     309                 :            : 
     310                 :        192 :             bool b = aComp(fVal);
     311   [ #  #  #  #  :        192 :             aNewMat.set(i, j, b);
          #  #  #  #  #  
                #  +  - ]
     312                 :            :         }
     313                 :            :     }
     314 [ #  # ][ #  # ]:         72 :     aNewMat.swap(rMat);
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
     315                 :         72 : }
     316                 :            : 
     317                 :            : }
     318                 :            : 
     319                 :            : class ScMatrixImpl
     320                 :            : {
     321                 :            :     MatrixImplType maMat;
     322                 :            :     MatrixImplType maMatFlag;
     323                 :            :     ScInterpreter* pErrorInterpreter;
     324                 :            :     bool            mbCloneIfConst; // Whether the matrix is cloned with a CloneIfConst() call.
     325                 :            :     MatrixImplType::size_pair_type  maCachedSize;
     326                 :            : 
     327                 :            :     ScMatrixImpl();
     328                 :            :     ScMatrixImpl(const ScMatrixImpl&);
     329                 :            : public:
     330                 :            :     ScMatrixImpl(SCSIZE nC, SCSIZE nR);
     331                 :            :     ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal);
     332                 :            :     ~ScMatrixImpl();
     333                 :            : 
     334                 :            :     void Clear();
     335                 :            :     void SetImmutable(bool bVal);
     336                 :            :     bool IsImmutable() const;
     337                 :            :     void Resize(SCSIZE nC, SCSIZE nR);
     338                 :            :     void Resize(SCSIZE nC, SCSIZE nR, double fVal);
     339                 :            :     void SetErrorInterpreter( ScInterpreter* p);
     340                 :          0 :     ScInterpreter* GetErrorInterpreter() const { return pErrorInterpreter; }
     341                 :            : 
     342                 :            :     void GetDimensions( SCSIZE& rC, SCSIZE& rR) const;
     343                 :            :     SCSIZE GetElementCount() const;
     344                 :            :     bool ValidColRow( SCSIZE nC, SCSIZE nR) const;
     345                 :            :     bool ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const;
     346                 :            :     bool ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const;
     347                 :            :     void SetErrorAtInterpreter( sal_uInt16 nError ) const;
     348                 :            : 
     349                 :            :     void PutDouble(double fVal, SCSIZE nC, SCSIZE nR);
     350                 :            :     void PutDouble( double fVal, SCSIZE nIndex);
     351                 :            :     void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
     352                 :            : 
     353                 :            :     void PutString(const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR);
     354                 :            :     void PutString(const ::rtl::OUString& rStr, SCSIZE nIndex);
     355                 :            :     void PutString(const rtl::OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
     356                 :            : 
     357                 :            :     void PutEmpty(SCSIZE nC, SCSIZE nR);
     358                 :            :     void PutEmptyPath(SCSIZE nC, SCSIZE nR);
     359                 :            :     void PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR );
     360                 :            :     void PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR);
     361                 :            :     sal_uInt16 GetError( SCSIZE nC, SCSIZE nR) const;
     362                 :            :     double GetDouble(SCSIZE nC, SCSIZE nR) const;
     363                 :            :     double GetDouble( SCSIZE nIndex) const;
     364                 :            :     rtl::OUString GetString(SCSIZE nC, SCSIZE nR) const;
     365                 :            :     rtl::OUString GetString( SCSIZE nIndex) const;
     366                 :            :     rtl::OUString GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const;
     367                 :            :     ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const;
     368                 :            :     bool IsString( SCSIZE nIndex ) const;
     369                 :            :     bool IsString( SCSIZE nC, SCSIZE nR ) const;
     370                 :            :     bool IsEmpty( SCSIZE nC, SCSIZE nR ) const;
     371                 :            :     bool IsEmptyPath( SCSIZE nC, SCSIZE nR ) const;
     372                 :            :     bool IsValue( SCSIZE nIndex ) const;
     373                 :            :     bool IsValue( SCSIZE nC, SCSIZE nR ) const;
     374                 :            :     bool IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const;
     375                 :            :     bool IsBoolean( SCSIZE nC, SCSIZE nR ) const;
     376                 :            :     bool IsNumeric() const;
     377                 :            :     void MatCopy(ScMatrixImpl& mRes) const;
     378                 :            :     void MatTrans(ScMatrixImpl& mRes) const;
     379                 :            :     void FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 );
     380                 :            :     void CompareEqual();
     381                 :            :     void CompareNotEqual();
     382                 :            :     void CompareLess();
     383                 :            :     void CompareGreater();
     384                 :            :     void CompareLessEqual();
     385                 :            :     void CompareGreaterEqual();
     386                 :            :     double And() const;
     387                 :            :     double Or() const;
     388                 :            : 
     389                 :            :     ScMatrix::IterateResult Sum(bool bTextAsZero) const;
     390                 :            :     ScMatrix::IterateResult SumSquare(bool bTextAsZero) const;
     391                 :            :     ScMatrix::IterateResult Product(bool bTextAsZero) const;
     392                 :            :     size_t Count(bool bCountStrings) const;
     393                 :            : 
     394                 :            : private:
     395                 :            :     void CalcPosition(SCSIZE nIndex, SCSIZE& rC, SCSIZE& rR) const;
     396                 :            : };
     397                 :            : 
     398                 :        106 : ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR) :
     399         [ +  - ]:        106 :     maMat(nR, nC), maMatFlag(nR, nC), pErrorInterpreter(NULL), mbCloneIfConst(true) {}
     400                 :            : 
     401                 :        169 : ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal) :
     402         [ +  - ]:        169 :     maMat(nR, nC, fInitVal), maMatFlag(nR, nC), pErrorInterpreter(NULL), mbCloneIfConst(true) {}
     403                 :            : 
     404         [ +  - ]:        275 : ScMatrixImpl::~ScMatrixImpl()
     405                 :            : {
     406         [ +  - ]:        275 :     Clear();
     407                 :        275 : }
     408                 :            : 
     409                 :        275 : void ScMatrixImpl::Clear()
     410                 :            : {
     411                 :        275 :     maMat.clear();
     412                 :        275 :     maMatFlag.clear();
     413                 :        275 : }
     414                 :            : 
     415                 :        213 : void ScMatrixImpl::SetImmutable(bool bVal)
     416                 :            : {
     417                 :        213 :     mbCloneIfConst = bVal;
     418                 :        213 : }
     419                 :            : 
     420                 :          0 : bool ScMatrixImpl::IsImmutable() const
     421                 :            : {
     422                 :          0 :     return mbCloneIfConst;
     423                 :            : }
     424                 :            : 
     425                 :          3 : void ScMatrixImpl::Resize(SCSIZE nC, SCSIZE nR)
     426                 :            : {
     427                 :          3 :     maMat.resize(nR, nC);
     428                 :          3 : }
     429                 :            : 
     430                 :          3 : void ScMatrixImpl::Resize(SCSIZE nC, SCSIZE nR, double fVal)
     431                 :            : {
     432                 :          3 :     maMat.resize(nR, nC, fVal);
     433                 :          3 : }
     434                 :            : 
     435                 :        738 : void ScMatrixImpl::SetErrorInterpreter( ScInterpreter* p)
     436                 :            : {
     437                 :        738 :     pErrorInterpreter = p;
     438                 :        738 : }
     439                 :            : 
     440                 :        419 : void ScMatrixImpl::GetDimensions( SCSIZE& rC, SCSIZE& rR) const
     441                 :            : {
     442                 :        419 :     MatrixImplType::size_pair_type aSize = maMat.size();
     443                 :        419 :     rR = aSize.row;
     444                 :        419 :     rC = aSize.column;
     445                 :        419 : }
     446                 :            : 
     447                 :          0 : SCSIZE ScMatrixImpl::GetElementCount() const
     448                 :            : {
     449                 :          0 :     MatrixImplType::size_pair_type aSize = maMat.size();
     450                 :          0 :     return aSize.row * aSize.column;
     451                 :            : }
     452                 :            : 
     453                 :       2595 : bool ScMatrixImpl::ValidColRow( SCSIZE nC, SCSIZE nR) const
     454                 :            : {
     455                 :       2595 :     MatrixImplType::size_pair_type aSize = maMat.size();
     456 [ +  - ][ +  - ]:       2595 :     return nR < aSize.row && nC < aSize.column;
     457                 :            : }
     458                 :            : 
     459                 :        477 : bool ScMatrixImpl::ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const
     460                 :            : {
     461                 :        477 :     MatrixImplType::size_pair_type aSize = maMat.size();
     462 [ -  + ][ +  + ]:        477 :     if (aSize.column == 1 && aSize.row == 1)
     463                 :            :     {
     464                 :          0 :         rC = 0;
     465                 :          0 :         rR = 0;
     466                 :          0 :         return true;
     467                 :            :     }
     468 [ +  + ][ +  - ]:        477 :     else if (aSize.column == 1 && rR < aSize.row)
     469                 :            :     {
     470                 :            :         // single column matrix.
     471                 :        405 :         rC = 0;
     472                 :        405 :         return true;
     473                 :            :     }
     474 [ -  + ][ #  # ]:         72 :     else if (aSize.row == 1 && rC < aSize.column)
     475                 :            :     {
     476                 :            :         // single row matrix.
     477                 :          0 :         rR = 0;
     478                 :          0 :         return true;
     479                 :            :     }
     480                 :        477 :     return false;
     481                 :            : }
     482                 :            : 
     483                 :       1905 : bool ScMatrixImpl::ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const
     484                 :            : {
     485 [ -  + ][ #  # ]:       1905 :     return ValidColRow( rC, rR) || ValidColRowReplicated( rC, rR);
     486                 :            : }
     487                 :            : 
     488                 :          0 : void ScMatrixImpl::SetErrorAtInterpreter( sal_uInt16 nError ) const
     489                 :            : {
     490         [ #  # ]:          0 :     if ( pErrorInterpreter )
     491                 :          0 :         pErrorInterpreter->SetError( nError);
     492                 :          0 : }
     493                 :            : 
     494                 :        575 : void ScMatrixImpl::PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
     495                 :            : {
     496         [ +  - ]:        575 :     if (ValidColRow( nC, nR))
     497                 :        575 :         maMat.set(nR, nC, fVal);
     498                 :            :     else
     499                 :            :     {
     500                 :            :         OSL_FAIL("ScMatrixImpl::PutDouble: dimension error");
     501                 :            :     }
     502                 :        575 : }
     503                 :            : 
     504                 :         46 : void ScMatrixImpl::PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
     505                 :            : {
     506         [ +  - ]:         46 :     if (ValidColRow( nC, nR))
     507         [ +  - ]:         46 :         maMat.set(nR, nC, pArray, pArray + nLen);
     508                 :            :     else
     509                 :            :     {
     510                 :            :         OSL_FAIL("ScMatrixImpl::PutDouble: dimension error");
     511                 :            :     }
     512                 :         46 : }
     513                 :            : 
     514                 :        132 : void ScMatrixImpl::PutDouble( double fVal, SCSIZE nIndex)
     515                 :            : {
     516                 :            :     SCSIZE nC, nR;
     517         [ +  - ]:        132 :     CalcPosition(nIndex, nC, nR);
     518         [ +  - ]:        132 :     PutDouble(fVal, nC, nR);
     519                 :        132 : }
     520                 :            : 
     521                 :          9 : void ScMatrixImpl::PutString(const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR)
     522                 :            : {
     523         [ +  - ]:          9 :     if (ValidColRow( nC, nR))
     524                 :          9 :         maMat.set(nR, nC, rStr);
     525                 :            :     else
     526                 :            :     {
     527                 :            :         OSL_FAIL("ScMatrixImpl::PutString: dimension error");
     528                 :            :     }
     529                 :          9 : }
     530                 :            : 
     531                 :         36 : void ScMatrixImpl::PutString(const rtl::OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
     532                 :            : {
     533         [ +  - ]:         36 :     if (ValidColRow( nC, nR))
     534         [ +  - ]:         36 :         maMat.set(nR, nC, pArray, pArray + nLen);
     535                 :            :     else
     536                 :            :     {
     537                 :            :         OSL_FAIL("ScMatrixImpl::PutString: dimension error");
     538                 :            :     }
     539                 :         36 : }
     540                 :            : 
     541                 :          0 : void ScMatrixImpl::PutString(const ::rtl::OUString& rStr, SCSIZE nIndex)
     542                 :            : {
     543                 :            :     SCSIZE nC, nR;
     544         [ #  # ]:          0 :     CalcPosition(nIndex, nC, nR);
     545         [ #  # ]:          0 :     PutString(rStr, nC, nR);
     546                 :          0 : }
     547                 :            : 
     548                 :          0 : void ScMatrixImpl::PutEmpty(SCSIZE nC, SCSIZE nR)
     549                 :            : {
     550         [ #  # ]:          0 :     if (ValidColRow( nC, nR))
     551                 :            :     {
     552                 :          0 :         maMat.set_empty(nR, nC);
     553                 :          0 :         maMatFlag.set(nR, nC, false); // zero flag to indicate that this is 'empty', not 'empty path'.
     554                 :            :     }
     555                 :            :     else
     556                 :            :     {
     557                 :            :         OSL_FAIL("ScMatrixImpl::PutEmpty: dimension error");
     558                 :            :     }
     559                 :          0 : }
     560                 :            : 
     561                 :          3 : void ScMatrixImpl::PutEmptyPath(SCSIZE nC, SCSIZE nR)
     562                 :            : {
     563         [ +  - ]:          3 :     if (ValidColRow( nC, nR))
     564                 :            :     {
     565                 :          3 :         maMat.set_empty(nR, nC);
     566                 :          3 :         maMatFlag.set(nR, nC, true); // non-zero flag to indicate empty 'path'.
     567                 :            :     }
     568                 :            :     else
     569                 :            :     {
     570                 :            :         OSL_FAIL("ScMatrixImpl::PutEmptyPath: dimension error");
     571                 :            :     }
     572                 :          3 : }
     573                 :            : 
     574                 :          0 : void ScMatrixImpl::PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR )
     575                 :            : {
     576                 :          0 :     maMat.set(nR, nC, CreateDoubleError(nErrorCode));
     577                 :          0 : }
     578                 :            : 
     579                 :          9 : void ScMatrixImpl::PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR)
     580                 :            : {
     581         [ +  - ]:          9 :     if (ValidColRow( nC, nR))
     582                 :          9 :         maMat.set(nR, nC, bVal);
     583                 :            :     else
     584                 :            :     {
     585                 :            :         OSL_FAIL("ScMatrixImpl::PutBoolean: dimension error");
     586                 :            :     }
     587                 :          9 : }
     588                 :            : 
     589                 :          0 : sal_uInt16 ScMatrixImpl::GetError( SCSIZE nC, SCSIZE nR) const
     590                 :            : {
     591         [ #  # ]:          0 :     if (ValidColRowOrReplicated( nC, nR ))
     592                 :            :     {
     593                 :          0 :         double fVal = maMat.get_numeric(nR, nC);
     594                 :          0 :         return GetDoubleErrorValue(fVal);
     595                 :            :     }
     596                 :            :     else
     597                 :            :     {
     598                 :            :         OSL_FAIL("ScMatrixImpl::GetError: dimension error");
     599                 :          0 :         return errNoValue;
     600                 :            :     }
     601                 :            : }
     602                 :            : 
     603                 :        186 : double ScMatrixImpl::GetDouble(SCSIZE nC, SCSIZE nR) const
     604                 :            : {
     605         [ +  - ]:        186 :     if (ValidColRowOrReplicated( nC, nR ))
     606                 :            :     {
     607                 :        186 :         double fVal = maMat.get_numeric(nR, nC);
     608         [ -  + ]:        186 :         if ( pErrorInterpreter )
     609                 :            :         {
     610                 :          0 :             sal_uInt16 nError = GetDoubleErrorValue(fVal);
     611         [ #  # ]:          0 :             if ( nError )
     612                 :          0 :                 SetErrorAtInterpreter( nError);
     613                 :            :         }
     614                 :        186 :         return fVal;
     615                 :            :     }
     616                 :            :     else
     617                 :            :     {
     618                 :            :         OSL_FAIL("ScMatrixImpl::GetDouble: dimension error");
     619                 :        186 :         return CreateDoubleError( errNoValue);
     620                 :            :     }
     621                 :            : }
     622                 :            : 
     623                 :          0 : double ScMatrixImpl::GetDouble( SCSIZE nIndex) const
     624                 :            : {
     625                 :            :     SCSIZE nC, nR;
     626         [ #  # ]:          0 :     CalcPosition(nIndex, nC, nR);
     627         [ #  # ]:          0 :     return GetDouble(nC, nR);
     628                 :            : }
     629                 :            : 
     630                 :         96 : rtl::OUString ScMatrixImpl::GetString(SCSIZE nC, SCSIZE nR) const
     631                 :            : {
     632         [ +  - ]:         96 :     if (ValidColRowOrReplicated( nC, nR ))
     633                 :            :     {
     634                 :         96 :         double fErr = 0.0;
     635   [ +  -  -  -  :         96 :         switch (maMat.get_type(nR, nC))
                      - ]
     636                 :            :         {
     637                 :            :             case mdds::mtm::element_string:
     638                 :         96 :                 return maMat.get<rtl::OUString>(nR, nC);
     639                 :            :             case mdds::mtm::element_empty:
     640                 :          0 :                 return EMPTY_OUSTRING;
     641                 :            :             case mdds::mtm::element_numeric:
     642                 :            :                 OSL_FAIL("ScMatrixImpl::GetString: access error, no string");
     643                 :          0 :                 fErr = maMat.get<double>(nR, nC);
     644                 :          0 :             break;
     645                 :            :             case mdds::mtm::element_boolean:
     646                 :            :                 OSL_FAIL("ScMatrixImpl::GetString: access error, no string");
     647                 :          0 :                 fErr = maMat.get<bool>(nR, nC);
     648                 :          0 :             break;
     649                 :            :             default:
     650                 :            :                 OSL_FAIL("ScMatrixImpl::GetString: access error, no string");
     651                 :            :         }
     652                 :          0 :         SetErrorAtInterpreter(GetDoubleErrorValue(fErr));
     653                 :            :     }
     654                 :            :     else
     655                 :            :     {
     656                 :            :         OSL_FAIL("ScMatrixImpl::GetString: dimension error");
     657                 :            :     }
     658                 :         96 :     return EMPTY_OUSTRING;
     659                 :            : }
     660                 :            : 
     661                 :          0 : rtl::OUString ScMatrixImpl::GetString( SCSIZE nIndex) const
     662                 :            : {
     663                 :            :     SCSIZE nC, nR;
     664         [ #  # ]:          0 :     CalcPosition(nIndex, nC, nR);
     665         [ #  # ]:          0 :     return GetString(nC, nR);
     666                 :            : }
     667                 :            : 
     668                 :          0 : rtl::OUString ScMatrixImpl::GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const
     669                 :            : {
     670 [ #  # ][ #  # ]:          0 :     if (!ValidColRowOrReplicated( nC, nR ))
     671                 :            :     {
     672                 :            :         OSL_FAIL("ScMatrixImpl::GetString: dimension error");
     673                 :          0 :         return ::rtl::OUString();
     674                 :            :     }
     675                 :            : 
     676                 :          0 :     double fVal = 0.0;
     677 [ #  # ][ #  #  :          0 :     switch (maMat.get_type(nR, nC))
                #  #  # ]
     678                 :            :     {
     679                 :            :         case mdds::mtm::element_string:
     680         [ #  # ]:          0 :             return maMat.get<rtl::OUString>(nR, nC);
     681                 :            :         case mdds::mtm::element_empty:
     682                 :            :         {
     683 [ #  # ][ #  # ]:          0 :             if (!maMatFlag.get<bool>(nR, nC))
     684                 :            :                 // not an empty path.
     685                 :            :                 break;
     686                 :            : 
     687                 :            :             // result of empty FALSE jump path
     688                 :            :             sal_uLong nKey = rFormatter.GetStandardFormat( NUMBERFORMAT_LOGICAL,
     689         [ #  # ]:          0 :                     ScGlobal::eLnge);
     690                 :          0 :             ::rtl::OUString aStr;
     691                 :          0 :             Color* pColor = NULL;
     692         [ #  # ]:          0 :             rFormatter.GetOutputString( 0.0, nKey, aStr, &pColor);
     693                 :          0 :             return aStr;
     694                 :            :         }
     695                 :            :         case mdds::mtm::element_numeric:
     696         [ #  # ]:          0 :             fVal = maMat.get<double>(nR, nC);
     697                 :          0 :         break;
     698                 :            :         case mdds::mtm::element_boolean:
     699         [ #  # ]:          0 :             fVal = maMat.get<bool>(nR, nC);
     700                 :          0 :         break;
     701                 :            :         default:
     702                 :            :             ;
     703                 :            :     }
     704                 :            : 
     705                 :          0 :     sal_uInt16 nError = GetDoubleErrorValue(fVal);
     706         [ #  # ]:          0 :     if (nError)
     707                 :            :     {
     708                 :          0 :         SetErrorAtInterpreter( nError);
     709 [ #  # ][ #  # ]:          0 :         return ScGlobal::GetErrorString( nError);
                 [ #  # ]
     710                 :            :     }
     711                 :            : 
     712                 :            :     sal_uLong nKey = rFormatter.GetStandardFormat( NUMBERFORMAT_NUMBER,
     713         [ #  # ]:          0 :             ScGlobal::eLnge);
     714                 :          0 :     ::rtl::OUString aStr;
     715         [ #  # ]:          0 :     rFormatter.GetInputLineString( fVal, nKey, aStr);
     716                 :          0 :     return aStr;
     717                 :            : }
     718                 :            : 
     719                 :       1623 : ScMatrixValue ScMatrixImpl::Get(SCSIZE nC, SCSIZE nR) const
     720                 :            : {
     721                 :       1623 :     ScMatrixValue aVal;
     722 [ +  - ][ +  - ]:       1623 :     if (ValidColRowOrReplicated(nC, nR))
     723                 :            :     {
     724         [ +  - ]:       1623 :         mdds::mtm::element_t eType = maMat.get_type(nR, nC);
     725   [ +  +  +  +  :       1623 :         switch (eType)
                      - ]
     726                 :            :         {
     727                 :            :             case mdds::mtm::element_boolean:
     728                 :          3 :                 aVal.nType = SC_MATVAL_BOOLEAN;
     729         [ +  - ]:          3 :                 aVal.fVal = maMat.get_boolean(nR, nC);
     730                 :          3 :             break;
     731                 :            :             case mdds::mtm::element_numeric:
     732                 :        417 :                 aVal.nType = SC_MATVAL_VALUE;
     733         [ +  - ]:        417 :                 aVal.fVal = maMat.get_numeric(nR, nC);
     734                 :        417 :             break;
     735                 :            :             case mdds::mtm::element_string:
     736                 :          9 :                 aVal.nType = SC_MATVAL_STRING;
     737         [ +  - ]:          9 :                 aVal.aStr = maMat.get_string(nR, nC);
     738                 :          9 :             break;
     739                 :            :             case mdds::mtm::element_empty:
     740                 :            :                 // Empty path equals empty plus flag.
     741 [ +  - ][ +  + ]:       1194 :                 aVal.nType = maMatFlag.get<bool>(nR, nC) ? SC_MATVAL_EMPTYPATH : SC_MATVAL_EMPTY;
     742                 :       1623 :                 aVal.fVal = 0.0;
     743                 :            :             default:
     744                 :            :                 ;
     745                 :            :         }
     746                 :            :     }
     747                 :            :     else
     748                 :            :     {
     749                 :            :         OSL_FAIL("ScMatrixImpl::Get: dimension error");
     750                 :            :     }
     751                 :       1623 :     return aVal;
     752                 :            : }
     753                 :            : 
     754                 :          0 : bool ScMatrixImpl::IsString( SCSIZE nIndex ) const
     755                 :            : {
     756                 :            :     SCSIZE nC, nR;
     757         [ #  # ]:          0 :     CalcPosition(nIndex, nC, nR);
     758         [ #  # ]:          0 :     return IsString(nC, nR);
     759                 :            : }
     760                 :            : 
     761                 :         36 : bool ScMatrixImpl::IsString( SCSIZE nC, SCSIZE nR ) const
     762                 :            : {
     763                 :         36 :     ValidColRowReplicated( nC, nR );
     764         [ -  + ]:         36 :     switch (maMat.get_type(nR, nC))
     765                 :            :     {
     766                 :            :         case mdds::mtm::element_empty:
     767                 :            :         case mdds::mtm::element_string:
     768                 :          0 :             return true;
     769                 :            :         default:
     770                 :            :             ;
     771                 :            :     }
     772                 :         36 :     return false;
     773                 :            : }
     774                 :            : 
     775                 :        159 : bool ScMatrixImpl::IsEmpty( SCSIZE nC, SCSIZE nR ) const
     776                 :            : {
     777                 :            :     // Flag must be zero for this to be an empty element, instead of being an
     778                 :            :     // empty path element.
     779                 :        159 :     ValidColRowReplicated( nC, nR );
     780 [ +  - ][ +  + ]:        159 :     return maMat.get_type(nR, nC) == mdds::mtm::element_empty && !maMatFlag.get<bool>(nR, nC);
     781                 :            : }
     782                 :            : 
     783                 :          0 : bool ScMatrixImpl::IsEmptyPath( SCSIZE nC, SCSIZE nR ) const
     784                 :            : {
     785                 :            :     // 'Empty path' is empty plus non-zero flag.
     786         [ #  # ]:          0 :     if (ValidColRowOrReplicated( nC, nR ))
     787 [ #  # ][ #  # ]:          0 :         return maMat.get_type(nR, nC) == mdds::mtm::element_empty && maMatFlag.get<bool>(nR, nC);
     788                 :            :     else
     789                 :          0 :         return true;
     790                 :            : }
     791                 :            : 
     792                 :          0 : bool ScMatrixImpl::IsValue( SCSIZE nIndex ) const
     793                 :            : {
     794                 :            :     SCSIZE nC, nR;
     795         [ #  # ]:          0 :     CalcPosition(nIndex, nC, nR);
     796         [ #  # ]:          0 :     return IsValue(nC, nR);
     797                 :            : }
     798                 :            : 
     799                 :        246 : bool ScMatrixImpl::IsValue( SCSIZE nC, SCSIZE nR ) const
     800                 :            : {
     801                 :        246 :     ValidColRowReplicated(nC, nR);
     802         [ +  + ]:        246 :     switch (maMat.get_type(nR, nC))
     803                 :            :     {
     804                 :            :         case mdds::mtm::element_boolean:
     805                 :            :         case mdds::mtm::element_numeric:
     806                 :        150 :             return true;
     807                 :            :         default:
     808                 :            :             ;
     809                 :            :     }
     810                 :        246 :     return false;
     811                 :            : }
     812                 :            : 
     813                 :          0 : bool ScMatrixImpl::IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const
     814                 :            : {
     815                 :          0 :     ValidColRowReplicated(nC, nR);
     816         [ #  # ]:          0 :     switch (maMat.get_type(nR, nC))
     817                 :            :     {
     818                 :            :         case mdds::mtm::element_boolean:
     819                 :            :         case mdds::mtm::element_numeric:
     820                 :            :         case mdds::mtm::element_empty:
     821                 :          0 :             return true;
     822                 :            :         default:
     823                 :            :             ;
     824                 :            :     }
     825                 :          0 :     return false;
     826                 :            : }
     827                 :            : 
     828                 :         36 : bool ScMatrixImpl::IsBoolean( SCSIZE nC, SCSIZE nR ) const
     829                 :            : {
     830                 :         36 :     ValidColRowReplicated( nC, nR );
     831                 :         36 :     return maMat.get_type(nR, nC) == mdds::mtm::element_boolean;
     832                 :            : }
     833                 :            : 
     834                 :          3 : bool ScMatrixImpl::IsNumeric() const
     835                 :            : {
     836                 :          3 :     return maMat.numeric();
     837                 :            : }
     838                 :            : 
     839                 :          8 : void ScMatrixImpl::MatCopy(ScMatrixImpl& mRes) const
     840                 :            : {
     841 [ +  - ][ -  + ]:          8 :     if (maMat.size().row > mRes.maMat.size().row || maMat.size().column > mRes.maMat.size().column)
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ -  + ]
     842                 :            :     {
     843                 :            :         // destination matrix is not large enough.
     844                 :            :         OSL_FAIL("ScMatrixImpl::MatCopy: dimension error");
     845                 :          8 :         return;
     846                 :            :     }
     847                 :            : 
     848                 :          8 :     mRes.maMat.copy(maMat);
     849                 :            : }
     850                 :            : 
     851                 :          0 : void ScMatrixImpl::MatTrans(ScMatrixImpl& mRes) const
     852                 :            : {
     853                 :          0 :     mRes.maMat = maMat;
     854                 :          0 :     mRes.maMat.transpose();
     855                 :          0 : }
     856                 :            : 
     857                 :          6 : void ScMatrixImpl::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 )
     858                 :            : {
     859 [ +  - ][ +  - ]:          6 :     if (ValidColRow( nC1, nR1) && ValidColRow( nC2, nR2))
                 [ +  - ]
     860                 :            :     {
     861         [ +  + ]:         24 :         for (SCSIZE j = nC1; j <= nC2; ++j)
     862                 :            :         {
     863                 :            :             // Passing value array is much faster.
     864         [ +  - ]:         18 :             std::vector<double> aVals(nR2-nR1+1, fVal);
     865         [ +  - ]:         18 :             maMat.set(nR1, j, aVals.begin(), aVals.end());
     866                 :         18 :         }
     867                 :            :     }
     868                 :            :     else
     869                 :            :     {
     870                 :            :         OSL_FAIL("ScMatrixImpl::FillDouble: dimension error");
     871                 :            :     }
     872                 :          6 : }
     873                 :            : 
     874                 :         72 : void ScMatrixImpl::CompareEqual()
     875                 :            : {
     876                 :         72 :     compareMatrix<ElemEqualZero>(maMat);
     877                 :         72 : }
     878                 :            : 
     879                 :          0 : void ScMatrixImpl::CompareNotEqual()
     880                 :            : {
     881                 :          0 :     compareMatrix<ElemNotEqualZero>(maMat);
     882                 :          0 : }
     883                 :            : 
     884                 :          0 : void ScMatrixImpl::CompareLess()
     885                 :            : {
     886                 :          0 :     compareMatrix<ElemLessZero>(maMat);
     887                 :          0 : }
     888                 :            : 
     889                 :          0 : void ScMatrixImpl::CompareGreater()
     890                 :            : {
     891                 :          0 :     compareMatrix<ElemGreaterZero>(maMat);
     892                 :          0 : }
     893                 :            : 
     894                 :          0 : void ScMatrixImpl::CompareLessEqual()
     895                 :            : {
     896                 :          0 :     compareMatrix<ElemLessEqualZero>(maMat);
     897                 :          0 : }
     898                 :            : 
     899                 :          0 : void ScMatrixImpl::CompareGreaterEqual()
     900                 :            : {
     901                 :          0 :     compareMatrix<ElemGreaterEqualZero>(maMat);
     902                 :          0 : }
     903                 :            : 
     904                 :            : namespace {
     905                 :            : 
     906                 :            : struct AndEvaluator
     907                 :            : {
     908                 :        186 :     bool isBadElem(double fVal) const { return fVal == 0; }
     909                 :         15 :     bool returnOnElem() const { return false; }
     910                 :         24 :     bool returnOnAllElems() const { return true; }
     911                 :            : };
     912                 :            : 
     913                 :            : struct OrEvaluator
     914                 :            : {
     915                 :        279 :     bool isBadElem(double fVal) const { return fVal != 0; }
     916                 :         24 :     bool returnOnElem() const { return true; }
     917                 :         39 :     bool returnOnAllElems() const { return false; }
     918                 :            : };
     919                 :            : 
     920                 :            : template <typename _Evaluator>
     921                 :        102 : bool EvalMatrix(const MatrixImplType& rMat)
     922                 :            : {
     923                 :            :     _Evaluator aEval;
     924                 :        102 :     size_t nRows = rMat.size().row, nCols = rMat.size().column;
     925 [ +  + ][ +  + ]:        318 :     for (size_t i = 0; i < nRows; ++i)
     926                 :            :     {
     927 [ +  + ][ +  + ]:        681 :         for (size_t j = 0; j < nCols; ++j)
     928                 :            :         {
     929 [ +  - ][ +  - ]:        465 :             mdds::mtm::element_t eType = rMat.get_type(i, j);
     930 [ +  + ][ -  + ]:        465 :             if (eType != mdds::mtm::element_numeric && eType != mdds::mtm::element_boolean)
         [ +  + ][ -  + ]
     931                 :            :                 // assuming a CompareMat this is an error
     932                 :          0 :                 return CreateDoubleError(errIllegalArgument);
     933                 :            : 
     934 [ +  - ][ +  - ]:        465 :             double fVal = rMat.get_numeric(i, j);
     935 [ -  + ][ -  + ]:        465 :             if (!::rtl::math::isFinite(fVal))
     936                 :            :                 // DoubleError
     937                 :          0 :                 return fVal;
     938                 :            : 
     939 [ +  + ][ +  + ]:        465 :             if (aEval.isBadElem(fVal))
     940                 :         39 :                 return aEval.returnOnElem();
     941                 :            :         }
     942                 :            :     }
     943                 :        102 :     return aEval.returnOnAllElems();
     944                 :            : }
     945                 :            : 
     946                 :            : }
     947                 :            : 
     948                 :         39 : double ScMatrixImpl::And() const
     949                 :            : {
     950                 :            :     // All elements must be of value type.
     951                 :            :     // True only if all the elements have non-zero values.
     952                 :         39 :     return EvalMatrix<AndEvaluator>(maMat);
     953                 :            : }
     954                 :            : 
     955                 :         63 : double ScMatrixImpl::Or() const
     956                 :            : {
     957                 :            :     // All elements must be of value type.
     958                 :            :     // True if at least one element has a non-zero value.
     959                 :         63 :     return EvalMatrix<OrEvaluator>(maMat);
     960                 :            : }
     961                 :            : 
     962                 :            : namespace {
     963                 :            : 
     964                 :            : struct SumOp
     965                 :            : {
     966                 :            :     static const int InitVal = 0;
     967                 :            : 
     968                 :         42 :     void operator() (double& rAccum, double fVal)
     969                 :            :     {
     970                 :         42 :         rAccum += fVal;
     971                 :         42 :     }
     972                 :            : };
     973                 :            : 
     974                 :            : struct SumSquareOp
     975                 :            : {
     976                 :            :     static const int InitVal = 0;
     977                 :            : 
     978                 :          0 :     void operator() (double& rAccum, double fVal)
     979                 :            :     {
     980                 :          0 :         rAccum += fVal*fVal;
     981                 :          0 :     }
     982                 :            : };
     983                 :            : 
     984                 :            : struct ProductOp
     985                 :            : {
     986                 :            :     static const int InitVal = 1;
     987                 :            : 
     988                 :          9 :     void operator() (double& rAccum, double fVal)
     989                 :            :     {
     990                 :          9 :         rAccum *= fVal;
     991                 :          9 :     }
     992                 :            : };
     993                 :            : 
     994                 :            : template<typename _Op>
     995                 :            : class WalkElementBlocks : std::unary_function<MatrixImplType::element_block_node_type, void>
     996                 :            : {
     997                 :            :     _Op maOp;
     998                 :            : 
     999                 :            :     ScMatrix::IterateResult maRes;
    1000                 :            :     bool mbFirst:1;
    1001                 :            :     bool mbTextAsZero:1;
    1002                 :            : public:
    1003                 :         15 :     WalkElementBlocks(bool bTextAsZero) : maRes(0.0, _Op::InitVal, 0), mbFirst(true), mbTextAsZero(bTextAsZero) {}
    1004                 :            : 
    1005                 :         15 :     const ScMatrix::IterateResult& getResult() const { return maRes; }
    1006                 :            : 
    1007                 :         21 :     void operator() (const MatrixImplType::element_block_node_type& node)
    1008                 :            :     {
    1009   [ +  -  -  - ]:         21 :         switch (node.type)
           [ #  #  #  # ]
           [ +  -  -  + ]
    1010                 :            :         {
    1011                 :            :             case mdds::mtm::element_numeric:
    1012                 :            :             {
    1013                 :         15 :                 mdds::mtv::numeric_element_block::const_iterator it = mdds::mtv::numeric_element_block::begin(*node.data);
    1014                 :         15 :                 mdds::mtv::numeric_element_block::const_iterator itEnd = mdds::mtv::numeric_element_block::end(*node.data);
    1015 [ +  - ][ +  - ]:         66 :                 for (; it != itEnd; ++it)
         [ +  + ][ #  # ]
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
                 [ +  + ]
    1016                 :            :                 {
    1017 [ +  + ][ #  # ]:         51 :                     if (mbFirst)
                 [ +  + ]
    1018                 :            :                     {
    1019 [ +  - ][ #  # ]:         15 :                         maOp(maRes.mfFirst, *it);
                 [ +  - ]
    1020                 :         15 :                         mbFirst = false;
    1021                 :            :                     }
    1022                 :            :                     else
    1023 [ +  - ][ #  # ]:         36 :                         maOp(maRes.mfRest, *it);
                 [ +  - ]
    1024                 :            :                 }
    1025                 :         15 :                 maRes.mnCount += node.size;
    1026                 :            :             }
    1027                 :         15 :             break;
    1028                 :            :             case mdds::mtm::element_boolean:
    1029                 :            :             {
    1030                 :          0 :                 mdds::mtv::boolean_element_block::const_iterator it = mdds::mtv::boolean_element_block::begin(*node.data);
    1031                 :          0 :                 mdds::mtv::boolean_element_block::const_iterator itEnd = mdds::mtv::boolean_element_block::end(*node.data);
    1032 [ #  # ][ #  # ]:          0 :                 for (; it != itEnd; ++it)
                 [ #  # ]
    1033                 :            :                 {
    1034 [ #  # ][ #  # ]:          0 :                     if (mbFirst)
                 [ #  # ]
    1035                 :            :                     {
    1036                 :          0 :                         maOp(maRes.mfFirst, *it);
    1037                 :          0 :                         mbFirst = false;
    1038                 :            :                     }
    1039                 :            :                     else
    1040                 :          0 :                         maOp(maRes.mfRest, *it);
    1041                 :            :                 }
    1042                 :          0 :                 maRes.mnCount += node.size;
    1043                 :            :             }
    1044                 :          0 :             break;
    1045                 :            :             case mdds::mtm::element_string:
    1046 [ #  # ][ #  # ]:          0 :                 if (mbTextAsZero)
                 [ #  # ]
    1047                 :          0 :                     maRes.mnCount += node.size;
    1048                 :          0 :             break;
    1049                 :            :             case mdds::mtm::element_empty:
    1050                 :            :             default:
    1051                 :            :                 ;
    1052                 :            :         }
    1053                 :         21 :     }
    1054                 :            : };
    1055                 :            : 
    1056                 :            : class CountElements : std::unary_function<MatrixImplType::element_block_node_type, void>
    1057                 :            : {
    1058                 :            :     size_t mnCount;
    1059                 :            :     bool mbCountString;
    1060                 :            : public:
    1061                 :          6 :     CountElements(bool bCountString) : mnCount(0), mbCountString(bCountString) {}
    1062                 :            : 
    1063                 :          6 :     size_t getCount() const { return mnCount; }
    1064                 :            : 
    1065                 :          9 :     void operator() (const MatrixImplType::element_block_node_type& node)
    1066                 :            :     {
    1067      [ +  -  + ]:          9 :         switch (node.type)
    1068                 :            :         {
    1069                 :            :             case mdds::mtm::element_numeric:
    1070                 :            :             case mdds::mtm::element_boolean:
    1071                 :          6 :                 mnCount += node.size;
    1072                 :          6 :             break;
    1073                 :            :             case mdds::mtm::element_string:
    1074         [ #  # ]:          0 :                 if (mbCountString)
    1075                 :          0 :                     mnCount += node.size;
    1076                 :          0 :             break;
    1077                 :            :             case mdds::mtm::element_empty:
    1078                 :            :             default:
    1079                 :            :                 ;
    1080                 :            :         }
    1081                 :          9 :     }
    1082                 :            : };
    1083                 :            : 
    1084                 :            : }
    1085                 :            : 
    1086                 :         12 : ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const
    1087                 :            : {
    1088                 :         12 :     WalkElementBlocks<SumOp> aFunc(bTextAsZero);
    1089         [ +  - ]:         12 :     maMat.walk(aFunc);
    1090                 :         12 :     return aFunc.getResult();
    1091                 :            : }
    1092                 :            : 
    1093                 :          0 : ScMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const
    1094                 :            : {
    1095                 :          0 :     WalkElementBlocks<SumSquareOp> aFunc(bTextAsZero);
    1096         [ #  # ]:          0 :     maMat.walk(aFunc);
    1097                 :          0 :     return aFunc.getResult();
    1098                 :            : }
    1099                 :            : 
    1100                 :          3 : ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const
    1101                 :            : {
    1102                 :          3 :     WalkElementBlocks<ProductOp> aFunc(bTextAsZero);
    1103         [ +  - ]:          3 :     maMat.walk(aFunc);
    1104                 :          3 :     ScMatrix::IterateResult aRes = aFunc.getResult();
    1105                 :          3 :     return aRes;
    1106                 :            : }
    1107                 :            : 
    1108                 :          6 : size_t ScMatrixImpl::Count(bool bCountStrings) const
    1109                 :            : {
    1110                 :          6 :     CountElements aFunc(bCountStrings);
    1111         [ +  - ]:          6 :     maMat.walk(aFunc);
    1112                 :          6 :     return aFunc.getCount();
    1113                 :            : }
    1114                 :            : 
    1115                 :        132 : void ScMatrixImpl::CalcPosition(SCSIZE nIndex, SCSIZE& rC, SCSIZE& rR) const
    1116                 :            : {
    1117                 :        132 :     SCSIZE nRowSize = maMat.size().row;
    1118                 :        132 :     rC = nIndex / nRowSize;
    1119                 :        132 :     rR = nIndex - rC*nRowSize;
    1120                 :        132 : }
    1121                 :            : 
    1122                 :            : // ============================================================================
    1123                 :            : 
    1124                 :        106 : ScMatrix::ScMatrix( SCSIZE nC, SCSIZE nR) :
    1125         [ +  - ]:        106 :     pImpl(new ScMatrixImpl(nC, nR)), nRefCnt(0) {}
    1126                 :            : 
    1127                 :        169 : ScMatrix::ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal) :
    1128         [ +  - ]:        169 :     pImpl(new ScMatrixImpl(nC, nR, fInitVal)), nRefCnt(0) {}
    1129                 :            : 
    1130                 :        275 : ScMatrix::~ScMatrix()
    1131                 :            : {
    1132         [ +  - ]:        275 :     delete pImpl;
    1133                 :        275 : }
    1134                 :            : 
    1135                 :          0 : ScMatrix* ScMatrix::Clone() const
    1136                 :            : {
    1137                 :            :     SCSIZE nC, nR;
    1138         [ #  # ]:          0 :     pImpl->GetDimensions(nC, nR);
    1139 [ #  # ][ #  # ]:          0 :     ScMatrix* pScMat = new ScMatrix(nC, nR);
    1140         [ #  # ]:          0 :     MatCopy(*pScMat);
    1141         [ #  # ]:          0 :     pScMat->SetErrorInterpreter(pImpl->GetErrorInterpreter());    // TODO: really?
    1142                 :          0 :     return pScMat;
    1143                 :            : }
    1144                 :            : 
    1145                 :          0 : ScMatrix* ScMatrix::CloneIfConst()
    1146                 :            : {
    1147         [ #  # ]:          0 :     return pImpl->IsImmutable() ? Clone() : this;
    1148                 :            : }
    1149                 :            : 
    1150                 :        213 : void ScMatrix::SetImmutable( bool bVal )
    1151                 :            : {
    1152                 :        213 :     pImpl->SetImmutable(bVal);
    1153                 :        213 : }
    1154                 :            : 
    1155                 :          3 : void ScMatrix::Resize( SCSIZE nC, SCSIZE nR)
    1156                 :            : {
    1157                 :          3 :     pImpl->Resize(nC, nR);
    1158                 :          3 : }
    1159                 :            : 
    1160                 :          3 : void ScMatrix::Resize(SCSIZE nC, SCSIZE nR, double fVal)
    1161                 :            : {
    1162                 :          3 :     pImpl->Resize(nC, nR, fVal);
    1163                 :          3 : }
    1164                 :            : 
    1165                 :          0 : ScMatrix* ScMatrix::CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const
    1166                 :            : {
    1167         [ #  # ]:          0 :     ScMatrix* pScMat = new ScMatrix(nNewCols, nNewRows);
    1168                 :          0 :     MatCopy(*pScMat);
    1169                 :          0 :     pScMat->SetErrorInterpreter(pImpl->GetErrorInterpreter());
    1170                 :          0 :     return pScMat;
    1171                 :            : }
    1172                 :            : 
    1173                 :        738 : void ScMatrix::SetErrorInterpreter( ScInterpreter* p)
    1174                 :            : {
    1175                 :        738 :     pImpl->SetErrorInterpreter(p);
    1176                 :        738 : }
    1177                 :            : 
    1178                 :        419 : void ScMatrix::GetDimensions( SCSIZE& rC, SCSIZE& rR) const
    1179                 :            : {
    1180                 :        419 :     pImpl->GetDimensions(rC, rR);
    1181                 :        419 : }
    1182                 :            : 
    1183                 :          0 : SCSIZE ScMatrix::GetElementCount() const
    1184                 :            : {
    1185                 :          0 :     return pImpl->GetElementCount();
    1186                 :            : }
    1187                 :            : 
    1188                 :          0 : bool ScMatrix::ValidColRow( SCSIZE nC, SCSIZE nR) const
    1189                 :            : {
    1190                 :          0 :     return pImpl->ValidColRow(nC, nR);
    1191                 :            : }
    1192                 :            : 
    1193                 :          0 : bool ScMatrix::ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const
    1194                 :            : {
    1195                 :          0 :     return pImpl->ValidColRowReplicated(rC, rR);
    1196                 :            : }
    1197                 :            : 
    1198                 :          0 : bool ScMatrix::ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const
    1199                 :            : {
    1200 [ #  # ][ #  # ]:          0 :     return ValidColRow( rC, rR) || ValidColRowReplicated( rC, rR);
    1201                 :            : }
    1202                 :            : 
    1203                 :        443 : void ScMatrix::PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
    1204                 :            : {
    1205                 :        443 :     pImpl->PutDouble(fVal, nC, nR);
    1206                 :        443 : }
    1207                 :            : 
    1208                 :        132 : void ScMatrix::PutDouble( double fVal, SCSIZE nIndex)
    1209                 :            : {
    1210                 :        132 :     pImpl->PutDouble(fVal, nIndex);
    1211                 :        132 : }
    1212                 :            : 
    1213                 :         46 : void ScMatrix::PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
    1214                 :            : {
    1215                 :         46 :     pImpl->PutDouble(pArray, nLen, nC, nR);
    1216                 :         46 : }
    1217                 :            : 
    1218                 :          9 : void ScMatrix::PutString(const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR)
    1219                 :            : {
    1220                 :          9 :     pImpl->PutString(rStr, nC, nR);
    1221                 :          9 : }
    1222                 :            : 
    1223                 :          0 : void ScMatrix::PutString(const ::rtl::OUString& rStr, SCSIZE nIndex)
    1224                 :            : {
    1225                 :          0 :     pImpl->PutString(rStr, nIndex);
    1226                 :          0 : }
    1227                 :            : 
    1228                 :         36 : void ScMatrix::PutString(const rtl::OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
    1229                 :            : {
    1230                 :         36 :     pImpl->PutString(pArray, nLen, nC, nR);
    1231                 :         36 : }
    1232                 :            : 
    1233                 :          0 : void ScMatrix::PutEmpty(SCSIZE nC, SCSIZE nR)
    1234                 :            : {
    1235                 :          0 :     pImpl->PutEmpty(nC, nR);
    1236                 :          0 : }
    1237                 :            : 
    1238                 :          3 : void ScMatrix::PutEmptyPath(SCSIZE nC, SCSIZE nR)
    1239                 :            : {
    1240                 :          3 :     pImpl->PutEmptyPath(nC, nR);
    1241                 :          3 : }
    1242                 :            : 
    1243                 :          0 : void ScMatrix::PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR )
    1244                 :            : {
    1245                 :          0 :     pImpl->PutError(nErrorCode, nC, nR);
    1246                 :          0 : }
    1247                 :            : 
    1248                 :          9 : void ScMatrix::PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR)
    1249                 :            : {
    1250                 :          9 :     pImpl->PutBoolean(bVal, nC, nR);
    1251                 :          9 : }
    1252                 :            : 
    1253                 :          0 : sal_uInt16 ScMatrix::GetError( SCSIZE nC, SCSIZE nR) const
    1254                 :            : {
    1255                 :          0 :     return pImpl->GetError(nC, nR);
    1256                 :            : }
    1257                 :            : 
    1258                 :        186 : double ScMatrix::GetDouble(SCSIZE nC, SCSIZE nR) const
    1259                 :            : {
    1260                 :        186 :     return pImpl->GetDouble(nC, nR);
    1261                 :            : }
    1262                 :            : 
    1263                 :          0 : double ScMatrix::GetDouble( SCSIZE nIndex) const
    1264                 :            : {
    1265                 :          0 :     return pImpl->GetDouble(nIndex);
    1266                 :            : }
    1267                 :            : 
    1268                 :         96 : rtl::OUString ScMatrix::GetString(SCSIZE nC, SCSIZE nR) const
    1269                 :            : {
    1270                 :         96 :     return pImpl->GetString(nC, nR);
    1271                 :            : }
    1272                 :            : 
    1273                 :          0 : rtl::OUString ScMatrix::GetString( SCSIZE nIndex) const
    1274                 :            : {
    1275                 :          0 :     return pImpl->GetString(nIndex);
    1276                 :            : }
    1277                 :            : 
    1278                 :          0 : ::rtl::OUString ScMatrix::GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const
    1279                 :            : {
    1280                 :          0 :     return pImpl->GetString(rFormatter, nC, nR);
    1281                 :            : }
    1282                 :            : 
    1283                 :       1623 : ScMatrixValue ScMatrix::Get(SCSIZE nC, SCSIZE nR) const
    1284                 :            : {
    1285                 :       1623 :     return pImpl->Get(nC, nR);
    1286                 :            : }
    1287                 :            : 
    1288                 :          0 : sal_Bool ScMatrix::IsString( SCSIZE nIndex ) const
    1289                 :            : {
    1290                 :          0 :     return pImpl->IsString(nIndex);
    1291                 :            : }
    1292                 :            : 
    1293                 :         36 : sal_Bool ScMatrix::IsString( SCSIZE nC, SCSIZE nR ) const
    1294                 :            : {
    1295                 :         36 :     return pImpl->IsString(nC, nR);
    1296                 :            : }
    1297                 :            : 
    1298                 :        159 : sal_Bool ScMatrix::IsEmpty( SCSIZE nC, SCSIZE nR ) const
    1299                 :            : {
    1300                 :        159 :     return pImpl->IsEmpty(nC, nR);
    1301                 :            : }
    1302                 :            : 
    1303                 :          0 : sal_Bool ScMatrix::IsEmptyPath( SCSIZE nC, SCSIZE nR ) const
    1304                 :            : {
    1305                 :          0 :     return pImpl->IsEmptyPath(nC, nR);
    1306                 :            : }
    1307                 :            : 
    1308                 :          0 : sal_Bool ScMatrix::IsValue( SCSIZE nIndex ) const
    1309                 :            : {
    1310                 :          0 :     return pImpl->IsValue(nIndex);
    1311                 :            : }
    1312                 :            : 
    1313                 :        246 : sal_Bool ScMatrix::IsValue( SCSIZE nC, SCSIZE nR ) const
    1314                 :            : {
    1315                 :        246 :     return pImpl->IsValue(nC, nR);
    1316                 :            : }
    1317                 :            : 
    1318                 :          0 : sal_Bool ScMatrix::IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const
    1319                 :            : {
    1320                 :          0 :     return pImpl->IsValueOrEmpty(nC, nR);
    1321                 :            : }
    1322                 :            : 
    1323                 :         36 : sal_Bool ScMatrix::IsBoolean( SCSIZE nC, SCSIZE nR ) const
    1324                 :            : {
    1325                 :         36 :     return pImpl->IsBoolean(nC, nR);
    1326                 :            : }
    1327                 :            : 
    1328                 :          3 : sal_Bool ScMatrix::IsNumeric() const
    1329                 :            : {
    1330                 :          3 :     return pImpl->IsNumeric();
    1331                 :            : }
    1332                 :            : 
    1333                 :          8 : void ScMatrix::MatCopy(ScMatrix& mRes) const
    1334                 :            : {
    1335                 :          8 :     pImpl->MatCopy(*mRes.pImpl);
    1336                 :          8 : }
    1337                 :            : 
    1338                 :          0 : void ScMatrix::MatTrans(ScMatrix& mRes) const
    1339                 :            : {
    1340                 :          0 :     pImpl->MatTrans(*mRes.pImpl);
    1341                 :          0 : }
    1342                 :            : 
    1343                 :          6 : void ScMatrix::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 )
    1344                 :            : {
    1345                 :          6 :     pImpl->FillDouble(fVal, nC1, nR1, nC2, nR2);
    1346                 :          6 : }
    1347                 :            : 
    1348                 :         72 : void ScMatrix::CompareEqual()
    1349                 :            : {
    1350                 :         72 :     pImpl->CompareEqual();
    1351                 :         72 : }
    1352                 :            : 
    1353                 :          0 : void ScMatrix::CompareNotEqual()
    1354                 :            : {
    1355                 :          0 :     pImpl->CompareNotEqual();
    1356                 :          0 : }
    1357                 :            : 
    1358                 :          0 : void ScMatrix::CompareLess()
    1359                 :            : {
    1360                 :          0 :     pImpl->CompareLess();
    1361                 :          0 : }
    1362                 :            : 
    1363                 :          0 : void ScMatrix::CompareGreater()
    1364                 :            : {
    1365                 :          0 :     pImpl->CompareGreater();
    1366                 :          0 : }
    1367                 :            : 
    1368                 :          0 : void ScMatrix::CompareLessEqual()
    1369                 :            : {
    1370                 :          0 :     pImpl->CompareLessEqual();
    1371                 :          0 : }
    1372                 :            : 
    1373                 :          0 : void ScMatrix::CompareGreaterEqual()
    1374                 :            : {
    1375                 :          0 :     pImpl->CompareGreaterEqual();
    1376                 :          0 : }
    1377                 :            : 
    1378                 :         39 : double ScMatrix::And() const
    1379                 :            : {
    1380                 :         39 :     return pImpl->And();
    1381                 :            : }
    1382                 :            : 
    1383                 :         63 : double ScMatrix::Or() const
    1384                 :            : {
    1385                 :         63 :     return pImpl->Or();
    1386                 :            : }
    1387                 :            : 
    1388                 :         12 : ScMatrix::IterateResult ScMatrix::Sum(bool bTextAsZero) const
    1389                 :            : {
    1390                 :         12 :     return pImpl->Sum(bTextAsZero);
    1391                 :            : }
    1392                 :            : 
    1393                 :          0 : ScMatrix::IterateResult ScMatrix::SumSquare(bool bTextAsZero) const
    1394                 :            : {
    1395                 :          0 :     return pImpl->SumSquare(bTextAsZero);
    1396                 :            : }
    1397                 :            : 
    1398                 :          3 : ScMatrix::IterateResult ScMatrix::Product(bool bTextAsZero) const
    1399                 :            : {
    1400                 :          3 :     return pImpl->Product(bTextAsZero);
    1401                 :            : }
    1402                 :            : 
    1403                 :          6 : size_t ScMatrix::Count(bool bCountStrings) const
    1404                 :            : {
    1405                 :          6 :     return pImpl->Count(bCountStrings);
    1406 [ +  - ][ +  - ]:        153 : }
    1407                 :            : 
    1408                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10