Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sc / inc / scmatrix.hxx
blob9be335fbc06bda2dccfcb395f7cb7d32dda8c1de
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_SC_INC_SCMATRIX_HXX
21 #define INCLUDED_SC_INC_SCMATRIX_HXX
23 #include "global.hxx"
24 #include "matrixoperators.hxx"
25 #include "types.hxx"
26 #include <formula/errorcodes.hxx>
27 #include "scdllapi.h"
28 #include <rtl/ustring.hxx>
29 #include <svl/sharedstring.hxx>
30 #include <svl/sharedstringpool.hxx>
32 #include <functional>
33 #include <memory>
34 #include <utility>
35 #include <vector>
36 #include <boost/intrusive_ptr.hpp>
38 #define DEBUG_MATRIX 0
40 class ScInterpreter;
41 class SvNumberFormatter;
42 class ScMatrixImpl;
43 enum class FormulaError : sal_uInt16;
45 namespace formula { class DoubleVectorRefToken; }
47 namespace sc {
49 struct Compare;
50 struct CompareOptions;
54 /**
55 * Try NOT to use this struct. This struct should go away in a hopefully
56 * not so distant future.
58 struct ScMatrixValue
60 double fVal;
61 svl::SharedString aStr;
62 ScMatValType nType;
64 /// Only valid if ScMatrix methods indicate so!
65 const svl::SharedString& GetString() const { return aStr; }
67 /// Only valid if ScMatrix methods indicate that this is no string!
68 FormulaError GetError() const { return GetDoubleErrorValue(fVal); }
70 /// Only valid if ScMatrix methods indicate that this is a boolean
71 bool GetBoolean() const { return fVal != 0.0; }
73 ScMatrixValue() : fVal(0.0), nType(ScMatValType::Empty) {}
75 ScMatrixValue(const ScMatrixValue& r) :
76 fVal(r.fVal), aStr(r.aStr), nType(r.nType) {}
78 bool operator== (const ScMatrixValue& r) const
80 if (nType != r.nType)
81 return false;
83 switch (nType)
85 case ScMatValType::Value:
86 case ScMatValType::Boolean:
87 return fVal == r.fVal;
88 break;
89 default:
93 return aStr == r.aStr;
96 bool operator!= (const ScMatrixValue& r) const
98 return !operator==(r);
101 ScMatrixValue& operator= (const ScMatrixValue& r)
103 if (this == &r)
104 return *this;
106 nType = r.nType;
107 fVal = r.fVal;
108 aStr = r.aStr;
109 return *this;
113 /// Abstract base class for ScFullMatrix and ScVectorRefMatrix implementations.
114 class SC_DLLPUBLIC ScMatrix
116 mutable size_t nRefCnt; // reference count
117 mutable bool mbCloneIfConst; // Whether the matrix is cloned with a CloneIfConst() call.
119 ScMatrix( const ScMatrix& ) = delete;
120 ScMatrix& operator=( const ScMatrix&) = delete;
122 protected:
123 virtual ~ScMatrix() {}
125 public:
126 enum Op { Add, Sub, Mul, Div };
128 typedef std::function<void(size_t, size_t, double)> DoubleOpFunction;
129 typedef std::function<void(size_t, size_t, bool)> BoolOpFunction;
130 typedef std::function<void(size_t, size_t, svl::SharedString)> StringOpFunction;
131 typedef std::function<void(size_t, size_t)> EmptyOpFunction;
134 * When adding all numerical matrix elements for a scalar result such as
135 * summation, the interpreter wants to separate the first non-zero value
136 * with the rest of the summed values. This is necessary for better
137 * numerical stability, unless we sort all by absolute values before
138 * summing (not really an option) or use another algorithm, e.g. Kahan's
139 * summation algorithm,
140 * https://en.wikipedia.org/wiki/Kahan_summation_algorithm
142 struct IterateResult
144 double mfFirst;
145 double mfRest;
146 size_t mnCount;
148 IterateResult(double fFirst, double fRest, size_t nCount) :
149 mfFirst(fFirst), mfRest(fRest), mnCount(nCount) {}
151 IterateResult(const IterateResult& r) :
152 mfFirst(r.mfFirst), mfRest(r.mfRest), mnCount(r.mnCount) {}
155 /** Checks nC or nR for zero and uses GetElementsMax() whether a matrix of
156 the size of nC*nR could be allocated. A zero size (both nC and nR zero)
157 matrix is allowed for later resize.
159 bool static IsSizeAllocatable( SCSIZE nC, SCSIZE nR );
161 /// Value or boolean.
162 static bool IsValueType( ScMatValType nType )
164 return nType <= ScMatValType::Boolean;
167 /// Boolean.
168 static bool IsBooleanType( ScMatValType nType )
170 return nType == ScMatValType::Boolean;
173 /// String, empty or empty path, but not value nor boolean.
174 static bool IsNonValueType( ScMatValType nType )
176 return bool(nType & ScMatValType::NonvalueMask);
179 /** String, but not empty or empty path or any other type.
180 Not named IsStringType to prevent confusion because previously
181 IsNonValueType was named IsStringType. */
182 static bool IsRealStringType( ScMatValType nType )
184 return (nType & ScMatValType::NonvalueMask) == ScMatValType::String;
187 /// Empty, but not empty path or any other type.
188 static bool IsEmptyType( ScMatValType nType )
190 return (nType & ScMatValType::NonvalueMask) == ScMatValType::Empty;
193 /// Empty path, but not empty or any other type.
194 static bool IsEmptyPathType( ScMatValType nType )
196 return (nType & ScMatValType::NonvalueMask) == ScMatValType::EmptyPath;
199 ScMatrix() : nRefCnt(0), mbCloneIfConst(true) {}
201 /** Clone the matrix. */
202 virtual ScMatrix* Clone() const = 0;
204 /** Clone the matrix if mbCloneIfConst (immutable) is set, otherwise
205 return _this_ matrix, to be assigned to a ScMatrixRef. */
206 ScMatrix* CloneIfConst();
208 /** Set the matrix to mutable for CloneIfConst(), only the interpreter
209 should do this and know the consequences. */
210 void SetMutable();
212 /** Set the matrix to immutable for CloneIfConst(), only the interpreter
213 should do this and know the consequences. */
214 void SetImmutable() const;
217 * Resize the matrix to specified new dimension.
219 virtual void Resize(SCSIZE nC, SCSIZE nR) = 0;
221 virtual void Resize(SCSIZE nC, SCSIZE nR, double fVal) = 0;
223 /** Clone the matrix and extend it to the new size. nNewCols and nNewRows
224 MUST be at least of the size of the original matrix. */
225 virtual ScMatrix* CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const = 0;
227 void IncRef() const;
228 void DecRef() const;
230 virtual void SetErrorInterpreter( ScInterpreter* p) = 0;
231 virtual void GetDimensions( SCSIZE& rC, SCSIZE& rR) const = 0;
232 virtual SCSIZE GetElementCount() const = 0;
233 virtual bool ValidColRow( SCSIZE nC, SCSIZE nR) const = 0;
235 /** For a row vector or column vector, if the position does not point into
236 the vector but is a valid column or row offset it is adapted such that
237 it points to an element to be replicated, same column row 0 for a row
238 vector, same row column 0 for a column vector. Else, for a 2D matrix,
239 returns false.
241 virtual bool ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const = 0;
243 /** Checks if the matrix position is within the matrix. If it is not, for a
244 row vector or column vector the position is adapted such that it points
245 to an element to be replicated, same column row 0 for a row vector,
246 same row column 0 for a column vector. Else, for a 2D matrix and
247 position not within matrix, returns false.
249 virtual bool ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const = 0;
251 virtual void PutDouble( double fVal, SCSIZE nC, SCSIZE nR) = 0;
252 virtual void PutDouble( double fVal, SCSIZE nIndex) = 0;
253 virtual void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) = 0;
255 virtual void PutString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR) = 0;
256 virtual void PutString( const svl::SharedString& rStr, SCSIZE nIndex) = 0;
257 virtual void PutString( const svl::SharedString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) = 0;
259 virtual void PutEmpty( SCSIZE nC, SCSIZE nR) = 0;
261 /// Jump sal_False without path
262 virtual void PutEmptyPath( SCSIZE nC, SCSIZE nR) = 0;
263 virtual void PutError( FormulaError nErrorCode, SCSIZE nC, SCSIZE nR ) = 0;
264 virtual void PutBoolean( bool bVal, SCSIZE nC, SCSIZE nR) = 0;
266 virtual void FillDouble( double fVal,
267 SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 ) = 0;
269 /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */
270 virtual void PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR ) = 0;
272 /** Put a column vector of strings, starting at row nR, must fit into dimensions. */
273 virtual void PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR ) = 0;
275 /** Put a column vector of empties, starting at row nR, must fit into dimensions. */
276 virtual void PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) = 0;
278 /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */
279 virtual void PutEmptyResultVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) = 0;
281 /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */
282 virtual void PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) = 0;
284 /** May be used before obtaining the double value of an element to avoid
285 passing its NAN around.
286 @ATTENTION: MUST NOT be used if the element is a string!
287 Use GetErrorIfNotString() instead if not sure.
288 @returns 0 if no error, else one of err... constants */
289 virtual FormulaError GetError( SCSIZE nC, SCSIZE nR) const = 0;
291 /** Use in ScInterpreter to obtain the error code, if any.
292 @returns 0 if no error or string element, else one of err... constants */
293 FormulaError GetErrorIfNotString( SCSIZE nC, SCSIZE nR) const
294 { return IsValue( nC, nR) ? GetError( nC, nR) : FormulaError::NONE; }
296 /// @return 0.0 if empty or empty path, else value or DoubleError.
297 virtual double GetDouble( SCSIZE nC, SCSIZE nR) const = 0;
298 /// @return 0.0 if empty or empty path, else value or DoubleError.
299 virtual double GetDouble( SCSIZE nIndex) const = 0;
300 /// @return value or DoubleError or string converted to value.
301 virtual double GetDoubleWithStringConversion( SCSIZE nC, SCSIZE nR ) const = 0;
303 /// @return empty string if empty or empty path, else string content.
304 virtual svl::SharedString GetString( SCSIZE nC, SCSIZE nR) const = 0;
305 /// @return empty string if empty or empty path, else string content.
306 virtual svl::SharedString GetString( SCSIZE nIndex) const = 0;
308 /** @returns the matrix element's string if one is present, otherwise the
309 numerical value formatted as string, or in case of an error the error
310 string is returned; an empty string for empty, a "FALSE" string for
311 empty path. */
312 virtual svl::SharedString GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const = 0;
314 /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
315 /// an empty string!
316 virtual ScMatrixValue Get( SCSIZE nC, SCSIZE nR) const = 0;
318 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
319 path, in fact non-value. */
320 virtual bool IsStringOrEmpty( SCSIZE nIndex ) const = 0;
322 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
323 path, in fact non-value. */
324 virtual bool IsStringOrEmpty( SCSIZE nC, SCSIZE nR ) const = 0;
326 /// @return <TRUE/> if empty or empty cell or empty result, not empty path.
327 virtual bool IsEmpty( SCSIZE nC, SCSIZE nR ) const = 0;
329 /// @return <TRUE/> if empty cell, not empty or empty result or empty path.
330 virtual bool IsEmptyCell( SCSIZE nC, SCSIZE nR ) const = 0;
332 /// @return <TRUE/> if empty result, not empty or empty cell or empty path.
333 virtual bool IsEmptyResult( SCSIZE nC, SCSIZE nR ) const = 0;
335 /// @return <TRUE/> if empty path, not empty or empty cell or empty result.
336 virtual bool IsEmptyPath( SCSIZE nC, SCSIZE nR ) const = 0;
338 /// @return <TRUE/> if value or boolean.
339 virtual bool IsValue( SCSIZE nIndex ) const = 0;
341 /// @return <TRUE/> if value or boolean.
342 virtual bool IsValue( SCSIZE nC, SCSIZE nR ) const = 0;
344 /// @return <TRUE/> if value or boolean or empty or empty path.
345 virtual bool IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const = 0;
347 /// @return <TRUE/> if boolean.
348 virtual bool IsBoolean( SCSIZE nC, SCSIZE nR ) const = 0;
350 /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties
351 virtual bool IsNumeric() const = 0;
353 virtual void MatTrans( ScMatrix& mRes) const = 0;
354 virtual void MatCopy ( ScMatrix& mRes) const = 0;
356 // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values
357 virtual void CompareEqual() = 0;
358 virtual void CompareNotEqual() = 0;
359 virtual void CompareLess() = 0;
360 virtual void CompareGreater() = 0;
361 virtual void CompareLessEqual() = 0;
362 virtual void CompareGreaterEqual() = 0;
364 virtual double And() const = 0; // logical AND of all matrix values, or NAN
365 virtual double Or() const = 0; // logical OR of all matrix values, or NAN
366 virtual double Xor() const = 0; // logical XOR of all matrix values, or NAN
368 virtual IterateResult Sum(bool bTextAsZero) const = 0;
369 virtual IterateResult SumSquare(bool bTextAsZero) const = 0;
370 virtual IterateResult Product(bool bTextAsZero) const = 0;
371 virtual size_t Count(bool bCountStrings, bool bCountErrors) const = 0;
372 virtual size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const = 0;
373 virtual size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const = 0;
375 virtual double GetMaxValue( bool bTextAsZero ) const = 0;
376 virtual double GetMinValue( bool bTextAsZero ) const = 0;
377 virtual double GetGcd() const = 0;
378 virtual double GetLcm() const = 0;
380 virtual ScMatrixRef CompareMatrix(
381 sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const = 0;
384 * Convert the content of matrix into a linear array of numeric values.
385 * String elements are mapped to NaN's and empty elements are mapped to
386 * either NaN or zero values.
388 * @param bEmptyAsZero if true empty elements are mapped to zero values,
389 * otherwise they become NaN values.
391 virtual void GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero = true ) const = 0;
392 virtual void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const = 0;
394 virtual void NotOp(ScMatrix& rMat) = 0;
395 virtual void NegOp(ScMatrix& rMat) = 0;
396 virtual void AddOp(double fVal, ScMatrix& rMat) = 0;
397 virtual void SubOp(bool bFlag, double fVal, ScMatrix& rMat) = 0;
398 virtual void MulOp(double fVal, ScMatrix& rMat) = 0;
399 virtual void DivOp(bool bFlag, double fVal, ScMatrix& rMat) = 0;
400 virtual void PowOp(bool bFlag, double fVal, ScMatrix& rMat) = 0;
402 virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) = 0;
404 virtual void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, const std::pair<size_t, size_t>& rEndPos,
405 DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc,
406 EmptyOpFunction aEmptyFunc) const = 0;
408 virtual void MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef& xMat1, const ScMatrixRef& xMat2,
409 SvNumberFormatter& rFormatter, svl::SharedStringPool& rPool) = 0;
411 #if DEBUG_MATRIX
412 virtual void Dump() const = 0;
413 #endif
417 * Matrix data type that can store values of mixed types. Each element can
418 * be one of the following types: numeric, string, boolean, empty, and empty
419 * path.
421 class SC_DLLPUBLIC ScFullMatrix : public ScMatrix
423 friend class ScMatrixImpl;
425 std::unique_ptr<ScMatrixImpl> pImpl;
427 ScFullMatrix( const ScFullMatrix& ) = delete;
428 ScFullMatrix& operator=( const ScFullMatrix&) = delete;
430 public:
432 ScFullMatrix(SCSIZE nC, SCSIZE nR);
433 ScFullMatrix(SCSIZE nC, SCSIZE nR, double fInitVal);
435 ScFullMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals );
437 virtual ~ScFullMatrix() override;
439 /** Clone the matrix. */
440 virtual ScMatrix* Clone() const override;
443 * Resize the matrix to specified new dimension.
445 virtual void Resize( SCSIZE nC, SCSIZE nR) override;
447 virtual void Resize(SCSIZE nC, SCSIZE nR, double fVal) override;
449 /** Clone the matrix and extend it to the new size. nNewCols and nNewRows
450 MUST be at least of the size of the original matrix. */
451 virtual ScMatrix* CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const override;
453 virtual void SetErrorInterpreter( ScInterpreter* p) override;
454 virtual void GetDimensions( SCSIZE& rC, SCSIZE& rR) const override;
455 virtual SCSIZE GetElementCount() const override;
456 virtual bool ValidColRow( SCSIZE nC, SCSIZE nR) const override;
458 /** For a row vector or column vector, if the position does not point into
459 the vector but is a valid column or row offset it is adapted such that
460 it points to an element to be replicated, same column row 0 for a row
461 vector, same row column 0 for a column vector. Else, for a 2D matrix,
462 returns false.
464 virtual bool ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const override;
466 /** Checks if the matrix position is within the matrix. If it is not, for a
467 row vector or column vector the position is adapted such that it points
468 to an element to be replicated, same column row 0 for a row vector,
469 same row column 0 for a column vector. Else, for a 2D matrix and
470 position not within matrix, returns false.
472 virtual bool ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const override;
474 virtual void PutDouble( double fVal, SCSIZE nC, SCSIZE nR) override;
475 virtual void PutDouble( double fVal, SCSIZE nIndex) override;
476 virtual void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) override;
478 virtual void PutString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR) override;
479 virtual void PutString( const svl::SharedString& rStr, SCSIZE nIndex) override;
480 virtual void PutString( const svl::SharedString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) override;
482 virtual void PutEmpty( SCSIZE nC, SCSIZE nR) override;
484 /// Jump sal_False without path
485 virtual void PutEmptyPath( SCSIZE nC, SCSIZE nR) override;
486 virtual void PutError( FormulaError nErrorCode, SCSIZE nC, SCSIZE nR ) override;
487 virtual void PutBoolean( bool bVal, SCSIZE nC, SCSIZE nR) override;
489 virtual void FillDouble( double fVal,
490 SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 ) override;
492 /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */
493 virtual void PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR ) override;
495 /** Put a column vector of strings, starting at row nR, must fit into dimensions. */
496 virtual void PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR ) override;
498 /** Put a column vector of empties, starting at row nR, must fit into dimensions. */
499 virtual void PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) override;
501 /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */
502 virtual void PutEmptyResultVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) override;
504 /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */
505 virtual void PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR ) override;
507 /** May be used before obtaining the double value of an element to avoid
508 passing its NAN around.
509 @ATTENTION: MUST NOT be used if the element is a string!
510 Use GetErrorIfNotString() instead if not sure.
511 @returns 0 if no error, else one of err... constants */
512 virtual FormulaError GetError( SCSIZE nC, SCSIZE nR) const override;
514 /// @return 0.0 if empty or empty path, else value or DoubleError.
515 virtual double GetDouble( SCSIZE nC, SCSIZE nR) const override;
516 /// @return 0.0 if empty or empty path, else value or DoubleError.
517 virtual double GetDouble( SCSIZE nIndex) const override;
518 /// @return value or DoubleError or string converted to value.
519 virtual double GetDoubleWithStringConversion( SCSIZE nC, SCSIZE nR ) const override;
521 /// @return empty string if empty or empty path, else string content.
522 virtual svl::SharedString GetString( SCSIZE nC, SCSIZE nR) const override;
523 /// @return empty string if empty or empty path, else string content.
524 virtual svl::SharedString GetString( SCSIZE nIndex) const override;
526 /** @returns the matrix element's string if one is present, otherwise the
527 numerical value formatted as string, or in case of an error the error
528 string is returned; an empty string for empty, a "FALSE" string for
529 empty path. */
530 virtual svl::SharedString GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const override;
532 /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
533 /// an empty string!
534 virtual ScMatrixValue Get( SCSIZE nC, SCSIZE nR) const override;
536 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
537 path, in fact non-value. */
538 virtual bool IsStringOrEmpty( SCSIZE nIndex ) const override;
540 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
541 path, in fact non-value. */
542 virtual bool IsStringOrEmpty( SCSIZE nC, SCSIZE nR ) const override;
544 /// @return <TRUE/> if empty or empty cell or empty result, not empty path.
545 virtual bool IsEmpty( SCSIZE nC, SCSIZE nR ) const override;
547 /// @return <TRUE/> if empty cell, not empty or empty result or empty path.
548 virtual bool IsEmptyCell( SCSIZE nC, SCSIZE nR ) const override;
550 /// @return <TRUE/> if empty result, not empty or empty cell or empty path.
551 virtual bool IsEmptyResult( SCSIZE nC, SCSIZE nR ) const override;
553 /// @return <TRUE/> if empty path, not empty or empty cell or empty result.
554 virtual bool IsEmptyPath( SCSIZE nC, SCSIZE nR ) const override;
556 /// @return <TRUE/> if value or boolean.
557 virtual bool IsValue( SCSIZE nIndex ) const override;
559 /// @return <TRUE/> if value or boolean.
560 virtual bool IsValue( SCSIZE nC, SCSIZE nR ) const override;
562 /// @return <TRUE/> if value or boolean or empty or empty path.
563 virtual bool IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const override;
565 /// @return <TRUE/> if boolean.
566 virtual bool IsBoolean( SCSIZE nC, SCSIZE nR ) const override;
568 /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties
569 virtual bool IsNumeric() const override;
571 virtual void MatTrans( ScMatrix& mRes) const override;
572 virtual void MatCopy ( ScMatrix& mRes) const override;
574 // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values
575 virtual void CompareEqual() override;
576 virtual void CompareNotEqual() override;
577 virtual void CompareLess() override;
578 virtual void CompareGreater() override;
579 virtual void CompareLessEqual() override;
580 virtual void CompareGreaterEqual() override;
582 virtual double And() const override; // logical AND of all matrix values, or NAN
583 virtual double Or() const override; // logical OR of all matrix values, or NAN
584 virtual double Xor() const override; // logical XOR of all matrix values, or NAN
586 virtual IterateResult Sum(bool bTextAsZero) const override;
587 virtual IterateResult SumSquare(bool bTextAsZero) const override;
588 virtual IterateResult Product(bool bTextAsZero) const override;
589 virtual size_t Count(bool bCountStrings, bool bCountErrors) const override;
590 virtual size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const override;
591 virtual size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const override;
593 virtual double GetMaxValue( bool bTextAsZero ) const override;
594 virtual double GetMinValue( bool bTextAsZero ) const override;
595 virtual double GetGcd() const override;
596 virtual double GetLcm() const override;
598 virtual ScMatrixRef CompareMatrix(
599 sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const override;
602 * Convert the content of matrix into a linear array of numeric values.
603 * String elements are mapped to NaN's and empty elements are mapped to
604 * either NaN or zero values.
606 * @param bEmptyAsZero if true empty elements are mapped to zero values,
607 * otherwise they become NaN values.
609 virtual void GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero = true ) const override;
610 virtual void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const override;
612 virtual void NotOp(ScMatrix& rMat) override;
613 virtual void NegOp(ScMatrix& rMat) override;
614 virtual void AddOp(double fVal, ScMatrix& rMat) override;
615 virtual void SubOp(bool bFlag, double fVal, ScMatrix& rMat) override;
616 virtual void MulOp(double fVal, ScMatrix& rMat) override;
617 virtual void DivOp(bool bFlag, double fVal, ScMatrix& rMat) override;
618 virtual void PowOp(bool bFlag, double fVal, ScMatrix& rMat) override;
620 virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) override;
622 virtual void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, const std::pair<size_t, size_t>& rEndPos,
623 DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc,
624 EmptyOpFunction aEmptyFunc) const override;
625 ScFullMatrix& operator+= ( const ScFullMatrix& r );
627 virtual void MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef& xMat1, const ScMatrixRef& xMat2,
628 SvNumberFormatter& rFormatter, svl::SharedStringPool& rPool) override;
630 #if DEBUG_MATRIX
631 virtual void Dump() const override;
632 #endif
635 class SC_DLLPUBLIC ScVectorRefMatrix : public ScMatrix
637 const formula::DoubleVectorRefToken* mpToken;
638 ScInterpreter* mpErrorInterpreter;
640 /// For the operations that are not fully implemented, create a ScFullMatrix, and operate on it.
641 std::unique_ptr<ScFullMatrix> mpFullMatrix;
643 SCSIZE mnRowStart;
644 SCSIZE mnRowSize;
646 ScVectorRefMatrix( const ScVectorRefMatrix& ) = delete;
647 ScVectorRefMatrix& operator=( const ScVectorRefMatrix&) = delete;
649 /// For the operations that are not fully implemented, create a ScFullMatrix, and operate on it.
651 /// Note: This is potentially an expensive operation.
652 /// TODO: Implement as much as possible directly using the DoubleVectorRefToken.
653 void ensureFullMatrix();
655 public:
657 ScVectorRefMatrix(const formula::DoubleVectorRefToken* pToken, SCSIZE nRowStart, SCSIZE nRowSize);
659 virtual ~ScVectorRefMatrix() override;
661 /** Clone the matrix. */
662 virtual ScMatrix* Clone() const override;
665 * Resize the matrix to specified new dimension.
667 virtual void Resize(SCSIZE nC, SCSIZE nR) override;
669 virtual void Resize(SCSIZE nC, SCSIZE nR, double fVal) override;
671 /** Clone the matrix and extend it to the new size. nNewCols and nNewRows
672 MUST be at least of the size of the original matrix. */
673 virtual ScMatrix* CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const override;
675 virtual void SetErrorInterpreter(ScInterpreter* p) override;
676 virtual void GetDimensions(SCSIZE& rC, SCSIZE& rR) const override;
677 virtual SCSIZE GetElementCount() const override;
678 virtual bool ValidColRow( SCSIZE nC, SCSIZE nR) const override;
680 /** For a row vector or column vector, if the position does not point into
681 the vector but is a valid column or row offset it is adapted such that
682 it points to an element to be replicated, same column row 0 for a row
683 vector, same row column 0 for a column vector. Else, for a 2D matrix,
684 returns false.
686 virtual bool ValidColRowReplicated(SCSIZE & rC, SCSIZE & rR) const override;
688 /** Checks if the matrix position is within the matrix. If it is not, for a
689 row vector or column vector the position is adapted such that it points
690 to an element to be replicated, same column row 0 for a row vector,
691 same row column 0 for a column vector. Else, for a 2D matrix and
692 position not within matrix, returns false.
694 virtual bool ValidColRowOrReplicated(SCSIZE & rC, SCSIZE & rR) const override;
696 virtual void PutDouble(double fVal, SCSIZE nC, SCSIZE nR) override;
697 virtual void PutDouble(double fVal, SCSIZE nIndex) override;
698 virtual void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) override;
700 virtual void PutString(const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR) override;
701 virtual void PutString(const svl::SharedString& rStr, SCSIZE nIndex) override;
702 virtual void PutString(const svl::SharedString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR) override;
704 virtual void PutEmpty(SCSIZE nC, SCSIZE nR) override;
706 /// Jump sal_False without path
707 virtual void PutEmptyPath(SCSIZE nC, SCSIZE nR) override;
708 virtual void PutError(FormulaError nErrorCode, SCSIZE nC, SCSIZE nR ) override;
709 virtual void PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR) override;
711 virtual void FillDouble(double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2) override;
713 /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */
714 virtual void PutDoubleVector(const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR) override;
716 /** Put a column vector of strings, starting at row nR, must fit into dimensions. */
717 virtual void PutStringVector(const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR) override;
719 /** Put a column vector of empties, starting at row nR, must fit into dimensions. */
720 virtual void PutEmptyVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR) override;
722 /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */
723 virtual void PutEmptyResultVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR) override;
725 /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */
726 virtual void PutEmptyPathVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR) override;
728 /** May be used before obtaining the double value of an element to avoid
729 passing its NAN around.
730 @ATTENTION: MUST NOT be used if the element is a string!
731 Use GetErrorIfNotString() instead if not sure.
732 @returns 0 if no error, else one of err... constants */
733 virtual FormulaError GetError(SCSIZE nC, SCSIZE nR) const override;
735 /// @return 0.0 if empty or empty path, else value or DoubleError.
736 virtual double GetDouble(SCSIZE nC, SCSIZE nR) const override;
737 /// @return 0.0 if empty or empty path, else value or DoubleError.
738 virtual double GetDouble(SCSIZE nIndex) const override;
739 /// @return value or DoubleError or string converted to value.
740 virtual double GetDoubleWithStringConversion( SCSIZE nC, SCSIZE nR ) const override;
742 /// @return empty string if empty or empty path, else string content.
743 virtual svl::SharedString GetString(SCSIZE nC, SCSIZE nR) const override;
744 /// @return empty string if empty or empty path, else string content.
745 virtual svl::SharedString GetString(SCSIZE nIndex) const override;
747 /** @returns the matrix element's string if one is present, otherwise the
748 numerical value formatted as string, or in case of an error the error
749 string is returned; an empty string for empty, a "FALSE" string for
750 empty path. */
751 virtual svl::SharedString GetString(SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const override;
753 /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
754 /// an empty string!
755 virtual ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const override;
757 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
758 path, in fact non-value. */
759 virtual bool IsStringOrEmpty(SCSIZE nIndex) const override;
761 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
762 path, in fact non-value. */
763 virtual bool IsStringOrEmpty(SCSIZE nC, SCSIZE nR) const override;
765 /// @return <TRUE/> if empty or empty cell or empty result, not empty path.
766 virtual bool IsEmpty(SCSIZE nC, SCSIZE nR) const override;
768 /// @return <TRUE/> if empty cell, not empty or empty result or empty path.
769 virtual bool IsEmptyCell(SCSIZE nC, SCSIZE nR) const override;
771 /// @return <TRUE/> if empty result, not empty or empty cell or empty path.
772 virtual bool IsEmptyResult(SCSIZE nC, SCSIZE nR) const override;
774 /// @return <TRUE/> if empty path, not empty or empty cell or empty result.
775 virtual bool IsEmptyPath(SCSIZE nC, SCSIZE nR) const override;
777 /// @return <TRUE/> if value or boolean.
778 virtual bool IsValue(SCSIZE nIndex) const override;
780 /// @return <TRUE/> if value or boolean.
781 virtual bool IsValue(SCSIZE nC, SCSIZE nR) const override;
783 /// @return <TRUE/> if value or boolean or empty or empty path.
784 virtual bool IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const override;
786 /// @return <TRUE/> if boolean.
787 virtual bool IsBoolean(SCSIZE nC, SCSIZE nR) const override;
789 /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties
790 virtual bool IsNumeric() const override;
792 virtual void MatTrans(ScMatrix& mRes) const override;
793 virtual void MatCopy (ScMatrix& mRes) const override;
795 // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values
796 virtual void CompareEqual() override;
797 virtual void CompareNotEqual() override;
798 virtual void CompareLess() override;
799 virtual void CompareGreater() override;
800 virtual void CompareLessEqual() override;
801 virtual void CompareGreaterEqual() override;
803 virtual double And() const override; // logical AND of all matrix values, or NAN
804 virtual double Or() const override; // logical OR of all matrix values, or NAN
805 virtual double Xor() const override; // logical XOR of all matrix values, or NAN
807 virtual IterateResult Sum(bool bTextAsZero) const override;
808 virtual IterateResult SumSquare(bool bTextAsZero) const override;
809 virtual IterateResult Product(bool bTextAsZero) const override;
810 virtual size_t Count(bool bCountStrings, bool bCountErrors) const override;
811 virtual size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const override;
812 virtual size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const override;
814 virtual double GetMaxValue(bool bTextAsZero) const override;
815 virtual double GetMinValue(bool bTextAsZero) const override;
816 virtual double GetGcd() const override;
817 virtual double GetLcm() const override;
819 virtual ScMatrixRef CompareMatrix(sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions) const override;
822 * Convert the content of matrix into a linear array of numeric values.
823 * String elements are mapped to NaN's and empty elements are mapped to
824 * either NaN or zero values.
826 * @param bEmptyAsZero if true empty elements are mapped to zero values,
827 * otherwise they become NaN values.
829 virtual void GetDoubleArray(std::vector<double>& rVector, bool bEmptyAsZero = true) const override;
830 virtual void MergeDoubleArray(std::vector<double>& rVector, Op eOp) const override;
832 virtual void NotOp(ScMatrix& rMat) override;
833 virtual void NegOp(ScMatrix& rMat) override;
834 virtual void AddOp(double fVal, ScMatrix& rMat) override;
835 virtual void SubOp(bool bFlag, double fVal, ScMatrix& rMat) override;
836 virtual void MulOp(double fVal, ScMatrix& rMat) override;
837 virtual void DivOp(bool bFlag, double fVal, ScMatrix& rMat) override;
838 virtual void PowOp(bool bFlag, double fVal, ScMatrix& rMat) override;
840 virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) override;
842 virtual void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, const std::pair<size_t, size_t>& rEndPos,
843 DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc,
844 EmptyOpFunction aEmptyFunc) const override;
846 ScVectorRefMatrix& operator+=(const ScVectorRefMatrix& r);
848 virtual void MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef& xMat1, const ScMatrixRef& xMat2,
849 SvNumberFormatter& rFormatter, svl::SharedStringPool& rPool) override;
851 #if DEBUG_MATRIX
852 virtual void Dump() const override
855 #endif
858 inline void intrusive_ptr_add_ref(const ScMatrix* p)
860 p->IncRef();
863 inline void intrusive_ptr_release(const ScMatrix* p)
865 p->DecRef();
868 #endif // INCLUDED_SC_INC_SCMATRIX_HXX
870 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */