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