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: */
|