LCOV - code coverage report
Current view: top level - libreoffice/sc/source/core/tool - scmatrix.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 314 562 55.9 %
Date: 2012-12-27 Functions: 100 178 56.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10