1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
24 #include "matrixoperators.hxx"
26 #include <formula/errorcodes.hxx>
28 #include <rtl/ustring.hxx>
29 #include <svl/sharedstring.hxx>
30 #include <svl/sharedstringpool.hxx>
36 #include <boost/intrusive_ptr.hpp>
38 #define DEBUG_MATRIX 0
41 class SvNumberFormatter
;
44 namespace formula
{ class DoubleVectorRefToken
; }
49 struct CompareOptions
;
54 * Try NOT to use this struct. This struct should go away in a hopefully
55 * not so distant future.
60 svl::SharedString aStr
;
63 /// Only valid if ScMatrix methods indicate so!
64 const svl::SharedString
& GetString() const { return aStr
; }
66 /// Only valid if ScMatrix methods indicate that this is no string!
67 sal_uInt16
GetError() const { return formula::GetDoubleErrorValue( fVal
); }
69 /// Only valid if ScMatrix methods indicate that this is a boolean
70 bool GetBoolean() const { return fVal
!= 0.0; }
72 ScMatrixValue() : fVal(0.0), nType(SC_MATVAL_EMPTY
) {}
74 ScMatrixValue(const ScMatrixValue
& r
) :
75 fVal(r
.fVal
), aStr(r
.aStr
), nType(r
.nType
) {}
77 bool operator== (const ScMatrixValue
& r
) const
85 case SC_MATVAL_BOOLEAN
:
86 return fVal
== r
.fVal
;
92 return aStr
== r
.aStr
;
95 bool operator!= (const ScMatrixValue
& r
) const
97 return !operator==(r
);
100 ScMatrixValue
& operator= (const ScMatrixValue
& r
)
112 /// Abstract base class for ScFullMatrix and ScVectorRefMatrix implementations.
113 class SC_DLLPUBLIC ScMatrix
115 mutable size_t nRefCnt
; // reference count
116 bool mbCloneIfConst
; // Whether the matrix is cloned with a CloneIfConst() call.
118 ScMatrix( const ScMatrix
& ) = delete;
119 ScMatrix
& operator=( const ScMatrix
&) = delete;
122 virtual ~ScMatrix() {}
125 enum Op
{ Add
, Sub
, Mul
, Div
};
127 typedef std::function
<void(size_t, size_t, double)> DoubleOpFunction
;
128 typedef std::function
<void(size_t, size_t, bool)> BoolOpFunction
;
129 typedef std::function
<void(size_t, size_t, svl::SharedString
)> StringOpFunction
;
130 typedef std::function
<void(size_t, size_t)> EmptyOpFunction
;
133 * When adding all numerical matrix elements for a scalar result such as
134 * summation, the interpreter wants to separate the first non-zero value
135 * with the rest of the summed values.
137 * TODO: Find out if we still need to do this. If not, we can re-write
138 * ScInterpreter::IterateParameters() to make it simpler and remove this
147 IterateResult(double fFirst
, double fRest
, size_t nCount
) :
148 mfFirst(fFirst
), mfRest(fRest
), mnCount(nCount
) {}
150 IterateResult(const IterateResult
& r
) :
151 mfFirst(r
.mfFirst
), mfRest(r
.mfRest
), mnCount(r
.mnCount
) {}
154 /// The maximum number of elements a matrix may have at runtime.
155 inline static size_t GetElementsMax()
160 // Roughly 125MB in total, divided by 8+1 per element => 14M elements.
161 const size_t nMemMax
= 0x08000000 / (sizeof(ScMatrixValue
) + sizeof(ScMatValType
));
162 // With MAXROWCOUNT==65536 and 128 columns => 8M elements ~72MB.
163 const size_t nArbitraryLimit
= (size_t)MAXROWCOUNT
* 128;
164 // Stuffed with a million rows would limit this to 14 columns.
165 return nMemMax
< nArbitraryLimit
? nMemMax
: nArbitraryLimit
;
169 /** Checks nC or nR for zero and uses GetElementsMax() whether a matrix of
170 the size of nC*nR could be allocated. A zero size (both nC and nR zero)
171 matrix is allowed for later resize.
173 bool static IsSizeAllocatable( SCSIZE nC
, SCSIZE nR
);
175 /// Value or boolean.
176 inline static bool IsValueType( ScMatValType nType
)
178 return nType
<= SC_MATVAL_BOOLEAN
;
182 inline static bool IsBooleanType( ScMatValType nType
)
184 return nType
== SC_MATVAL_BOOLEAN
;
187 /// String, empty or empty path, but not value nor boolean.
188 inline static bool IsNonValueType( ScMatValType nType
)
190 return (nType
& SC_MATVAL_NONVALUE
) != 0;
193 /** String, but not empty or empty path or any other type.
194 Not named IsStringType to prevent confusion because previously
195 IsNonValueType was named IsStringType. */
196 inline static bool IsRealStringType( ScMatValType nType
)
198 return (nType
& SC_MATVAL_NONVALUE
) == SC_MATVAL_STRING
;
201 /// Empty, but not empty path or any other type.
202 inline static bool IsEmptyType( ScMatValType nType
)
204 return (nType
& SC_MATVAL_NONVALUE
) == SC_MATVAL_EMPTY
;
207 /// Empty path, but not empty or any other type.
208 inline static bool IsEmptyPathType( ScMatValType nType
)
210 return (nType
& SC_MATVAL_NONVALUE
) == SC_MATVAL_EMPTYPATH
;
213 ScMatrix() : nRefCnt(0), mbCloneIfConst(true) {}
215 /** Clone the matrix. */
216 virtual ScMatrix
* Clone() const = 0;
218 /** Clone the matrix if mbCloneIfConst (immutable) is set, otherwise
219 return _this_ matrix, to be assigned to a ScMatrixRef. */
220 ScMatrix
* CloneIfConst();
222 /** Set the matrix to (im)mutable for CloneIfConst(), only the interpreter
223 should do this and know the consequences. */
224 void SetImmutable( bool bVal
);
227 * Resize the matrix to specified new dimension.
229 virtual void Resize(SCSIZE nC
, SCSIZE nR
) = 0;
231 virtual void Resize(SCSIZE nC
, SCSIZE nR
, double fVal
) = 0;
233 /** Clone the matrix and extend it to the new size. nNewCols and nNewRows
234 MUST be at least of the size of the original matrix. */
235 virtual ScMatrix
* CloneAndExtend(SCSIZE nNewCols
, SCSIZE nNewRows
) const = 0;
240 virtual void SetErrorInterpreter( ScInterpreter
* p
) = 0;
241 virtual void GetDimensions( SCSIZE
& rC
, SCSIZE
& rR
) const = 0;
242 virtual SCSIZE
GetElementCount() const = 0;
243 virtual bool ValidColRow( SCSIZE nC
, SCSIZE nR
) const = 0;
245 /** For a row vector or column vector, if the position does not point into
246 the vector but is a valid column or row offset it is adapted such that
247 it points to an element to be replicated, same column row 0 for a row
248 vector, same row column 0 for a column vector. Else, for a 2D matrix,
251 virtual bool ValidColRowReplicated( SCSIZE
& rC
, SCSIZE
& rR
) const = 0;
253 /** Checks if the matrix position is within the matrix. If it is not, for a
254 row vector or column vector the position is adapted such that it points
255 to an element to be replicated, same column row 0 for a row vector,
256 same row column 0 for a column vector. Else, for a 2D matrix and
257 position not within matrix, returns false.
259 virtual bool ValidColRowOrReplicated( SCSIZE
& rC
, SCSIZE
& rR
) const = 0;
261 virtual void PutDouble( double fVal
, SCSIZE nC
, SCSIZE nR
) = 0;
262 virtual void PutDouble( double fVal
, SCSIZE nIndex
) = 0;
263 virtual void PutDouble(const double* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) = 0;
265 virtual void PutString( const svl::SharedString
& rStr
, SCSIZE nC
, SCSIZE nR
) = 0;
266 virtual void PutString( const svl::SharedString
& rStr
, SCSIZE nIndex
) = 0;
267 virtual void PutString( const svl::SharedString
* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) = 0;
269 virtual void PutEmpty( SCSIZE nC
, SCSIZE nR
) = 0;
271 /// Jump sal_False without path
272 virtual void PutEmptyPath( SCSIZE nC
, SCSIZE nR
) = 0;
273 virtual void PutError( sal_uInt16 nErrorCode
, SCSIZE nC
, SCSIZE nR
) = 0;
274 virtual void PutBoolean( bool bVal
, SCSIZE nC
, SCSIZE nR
) = 0;
276 virtual void FillDouble( double fVal
,
277 SCSIZE nC1
, SCSIZE nR1
, SCSIZE nC2
, SCSIZE nR2
) = 0;
279 /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */
280 virtual void PutDoubleVector( const ::std::vector
< double > & rVec
, SCSIZE nC
, SCSIZE nR
) = 0;
282 /** Put a column vector of strings, starting at row nR, must fit into dimensions. */
283 virtual void PutStringVector( const ::std::vector
< svl::SharedString
> & rVec
, SCSIZE nC
, SCSIZE nR
) = 0;
285 /** Put a column vector of empties, starting at row nR, must fit into dimensions. */
286 virtual void PutEmptyVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) = 0;
288 /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */
289 virtual void PutEmptyResultVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) = 0;
291 /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */
292 virtual void PutEmptyPathVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) = 0;
294 /** May be used before obtaining the double value of an element to avoid
295 passing its NAN around.
296 @ATTENTION: MUST NOT be used if the element is a string!
297 Use GetErrorIfNotString() instead if not sure.
298 @returns 0 if no error, else one of err... constants */
299 virtual sal_uInt16
GetError( SCSIZE nC
, SCSIZE nR
) const = 0;
301 /** Use in ScInterpreter to obtain the error code, if any.
302 @returns 0 if no error or string element, else one of err... constants */
303 sal_uInt16
GetErrorIfNotString( SCSIZE nC
, SCSIZE nR
) const
304 { return IsValue( nC
, nR
) ? GetError( nC
, nR
) : 0; }
306 /// @return 0.0 if empty or empty path, else value or DoubleError.
307 virtual double GetDouble( SCSIZE nC
, SCSIZE nR
) const = 0;
308 /// @return 0.0 if empty or empty path, else value or DoubleError.
309 virtual double GetDouble( SCSIZE nIndex
) const = 0;
310 /// @return value or DoubleError or string converted to value.
311 virtual double GetDoubleWithStringConversion( SCSIZE nC
, SCSIZE nR
) const = 0;
313 /// @return empty string if empty or empty path, else string content.
314 virtual svl::SharedString
GetString( SCSIZE nC
, SCSIZE nR
) const = 0;
315 /// @return empty string if empty or empty path, else string content.
316 virtual svl::SharedString
GetString( SCSIZE nIndex
) const = 0;
318 /** @returns the matrix element's string if one is present, otherwise the
319 numerical value formatted as string, or in case of an error the error
320 string is returned; an empty string for empty, a "FALSE" string for
322 virtual svl::SharedString
GetString( SvNumberFormatter
& rFormatter
, SCSIZE nC
, SCSIZE nR
) const = 0;
324 /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
326 virtual ScMatrixValue
Get( SCSIZE nC
, SCSIZE nR
) const = 0;
328 /// @return <TRUE/> if string or empty or empty path, in fact non-value.
329 virtual bool IsString( SCSIZE nIndex
) const = 0;
331 /// @return <TRUE/> if string or empty or empty path, in fact non-value.
332 virtual bool IsString( SCSIZE nC
, SCSIZE nR
) const = 0;
334 /// @return <TRUE/> if empty or empty cell or empty result, not empty path.
335 virtual bool IsEmpty( SCSIZE nC
, SCSIZE nR
) const = 0;
337 /// @return <TRUE/> if empty cell, not empty or empty result or empty path.
338 virtual bool IsEmptyCell( SCSIZE nC
, SCSIZE nR
) const = 0;
340 /// @return <TRUE/> if empty result, not empty or empty cell or empty path.
341 virtual bool IsEmptyResult( SCSIZE nC
, SCSIZE nR
) const = 0;
343 /// @return <TRUE/> if empty path, not empty or empty cell or empty result.
344 virtual bool IsEmptyPath( SCSIZE nC
, SCSIZE nR
) const = 0;
346 /// @return <TRUE/> if value or boolean.
347 virtual bool IsValue( SCSIZE nIndex
) const = 0;
349 /// @return <TRUE/> if value or boolean.
350 virtual bool IsValue( SCSIZE nC
, SCSIZE nR
) const = 0;
352 /// @return <TRUE/> if value or boolean or empty or empty path.
353 virtual bool IsValueOrEmpty( SCSIZE nC
, SCSIZE nR
) const = 0;
355 /// @return <TRUE/> if boolean.
356 virtual bool IsBoolean( SCSIZE nC
, SCSIZE nR
) const = 0;
358 /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties
359 virtual bool IsNumeric() const = 0;
361 virtual void MatTrans( ScMatrix
& mRes
) const = 0;
362 virtual void MatCopy ( ScMatrix
& mRes
) const = 0;
364 // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values
365 virtual void CompareEqual() = 0;
366 virtual void CompareNotEqual() = 0;
367 virtual void CompareLess() = 0;
368 virtual void CompareGreater() = 0;
369 virtual void CompareLessEqual() = 0;
370 virtual void CompareGreaterEqual() = 0;
372 virtual double And() const = 0; // logical AND of all matrix values, or NAN
373 virtual double Or() const = 0; // logical OR of all matrix values, or NAN
374 virtual double Xor() const = 0; // logical XOR of all matrix values, or NAN
376 virtual IterateResult
Sum(bool bTextAsZero
) const = 0;
377 virtual IterateResult
SumSquare(bool bTextAsZero
) const = 0;
378 virtual IterateResult
Product(bool bTextAsZero
) const = 0;
379 virtual size_t Count(bool bCountStrings
, bool bCountErrors
) const = 0;
380 virtual size_t MatchDoubleInColumns(double fValue
, size_t nCol1
, size_t nCol2
) const = 0;
381 virtual size_t MatchStringInColumns(const svl::SharedString
& rStr
, size_t nCol1
, size_t nCol2
) const = 0;
383 virtual double GetMaxValue( bool bTextAsZero
) const = 0;
384 virtual double GetMinValue( bool bTextAsZero
) const = 0;
386 virtual ScMatrixRef
CompareMatrix(
387 sc::Compare
& rComp
, size_t nMatPos
, sc::CompareOptions
* pOptions
= nullptr ) const = 0;
390 * Convert the content of matrix into a linear array of numeric values.
391 * String elements are mapped to NaN's and empty elements are mapped to
392 * either NaN or zero values.
394 * @param bEmptyAsZero if true empty elements are mapped to zero values,
395 * otherwise they become NaN values.
397 virtual void GetDoubleArray( std::vector
<double>& rArray
, bool bEmptyAsZero
= true ) const = 0;
398 virtual void MergeDoubleArray( std::vector
<double>& rArray
, Op eOp
) const = 0;
400 virtual void NotOp(ScMatrix
& rMat
) = 0;
401 virtual void NegOp(ScMatrix
& rMat
) = 0;
402 virtual void AddOp(double fVal
, ScMatrix
& rMat
) = 0;
403 virtual void SubOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) = 0;
404 virtual void MulOp(double fVal
, ScMatrix
& rMat
) = 0;
405 virtual void DivOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) = 0;
406 virtual void PowOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) = 0;
408 virtual std::vector
<ScMatrix::IterateResult
> Collect(bool bTextAsZero
, const std::vector
<std::unique_ptr
<sc::op::Op
>>& aOp
) = 0;
410 virtual void ExecuteOperation(const std::pair
<size_t, size_t>& rStartPos
, const std::pair
<size_t, size_t>& rEndPos
,
411 DoubleOpFunction aDoubleFunc
, BoolOpFunction aBoolFunc
, StringOpFunction aStringFunc
,
412 EmptyOpFunction aEmptyFunc
) const = 0;
414 virtual void MatConcat(SCSIZE nMaxCol
, SCSIZE nMaxRow
, const ScMatrixRef
& xMat1
, const ScMatrixRef
& xMat2
,
415 SvNumberFormatter
& rFormatter
, svl::SharedStringPool
& rPool
) = 0;
418 virtual void Dump() const = 0;
423 * Matrix data type that can store values of mixed types. Each element can
424 * be one of the following types: numeric, string, boolean, empty, and empty
427 class SC_DLLPUBLIC ScFullMatrix
: public ScMatrix
429 friend class ScMatrixImpl
;
431 std::unique_ptr
<ScMatrixImpl
> pImpl
;
433 ScFullMatrix( const ScFullMatrix
& ) = delete;
434 ScFullMatrix
& operator=( const ScFullMatrix
&) = delete;
438 ScFullMatrix(SCSIZE nC
, SCSIZE nR
);
439 ScFullMatrix(SCSIZE nC
, SCSIZE nR
, double fInitVal
);
441 ScFullMatrix( size_t nC
, size_t nR
, const std::vector
<double>& rInitVals
);
443 virtual ~ScFullMatrix();
445 /** Clone the matrix. */
446 virtual ScMatrix
* Clone() const override
;
449 * Resize the matrix to specified new dimension.
451 virtual void Resize( SCSIZE nC
, SCSIZE nR
) override
;
453 virtual void Resize(SCSIZE nC
, SCSIZE nR
, double fVal
) override
;
455 /** Clone the matrix and extend it to the new size. nNewCols and nNewRows
456 MUST be at least of the size of the original matrix. */
457 virtual ScMatrix
* CloneAndExtend(SCSIZE nNewCols
, SCSIZE nNewRows
) const override
;
459 virtual void SetErrorInterpreter( ScInterpreter
* p
) override
;
460 virtual void GetDimensions( SCSIZE
& rC
, SCSIZE
& rR
) const override
;
461 virtual SCSIZE
GetElementCount() const override
;
462 virtual bool ValidColRow( SCSIZE nC
, SCSIZE nR
) const override
;
464 /** For a row vector or column vector, if the position does not point into
465 the vector but is a valid column or row offset it is adapted such that
466 it points to an element to be replicated, same column row 0 for a row
467 vector, same row column 0 for a column vector. Else, for a 2D matrix,
470 virtual bool ValidColRowReplicated( SCSIZE
& rC
, SCSIZE
& rR
) const override
;
472 /** Checks if the matrix position is within the matrix. If it is not, for a
473 row vector or column vector the position is adapted such that it points
474 to an element to be replicated, same column row 0 for a row vector,
475 same row column 0 for a column vector. Else, for a 2D matrix and
476 position not within matrix, returns false.
478 virtual bool ValidColRowOrReplicated( SCSIZE
& rC
, SCSIZE
& rR
) const override
;
480 virtual void PutDouble( double fVal
, SCSIZE nC
, SCSIZE nR
) override
;
481 virtual void PutDouble( double fVal
, SCSIZE nIndex
) override
;
482 virtual void PutDouble(const double* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) override
;
484 virtual void PutString( const svl::SharedString
& rStr
, SCSIZE nC
, SCSIZE nR
) override
;
485 virtual void PutString( const svl::SharedString
& rStr
, SCSIZE nIndex
) override
;
486 virtual void PutString( const svl::SharedString
* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) override
;
488 virtual void PutEmpty( SCSIZE nC
, SCSIZE nR
) override
;
490 /// Jump sal_False without path
491 virtual void PutEmptyPath( SCSIZE nC
, SCSIZE nR
) override
;
492 virtual void PutError( sal_uInt16 nErrorCode
, SCSIZE nC
, SCSIZE nR
) override
;
493 virtual void PutBoolean( bool bVal
, SCSIZE nC
, SCSIZE nR
) override
;
495 virtual void FillDouble( double fVal
,
496 SCSIZE nC1
, SCSIZE nR1
, SCSIZE nC2
, SCSIZE nR2
) override
;
498 /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */
499 virtual void PutDoubleVector( const ::std::vector
< double > & rVec
, SCSIZE nC
, SCSIZE nR
) override
;
501 /** Put a column vector of strings, starting at row nR, must fit into dimensions. */
502 virtual void PutStringVector( const ::std::vector
< svl::SharedString
> & rVec
, SCSIZE nC
, SCSIZE nR
) override
;
504 /** Put a column vector of empties, starting at row nR, must fit into dimensions. */
505 virtual void PutEmptyVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
507 /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */
508 virtual void PutEmptyResultVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
510 /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */
511 virtual void PutEmptyPathVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
513 /** May be used before obtaining the double value of an element to avoid
514 passing its NAN around.
515 @ATTENTION: MUST NOT be used if the element is a string!
516 Use GetErrorIfNotString() instead if not sure.
517 @returns 0 if no error, else one of err... constants */
518 virtual sal_uInt16
GetError( SCSIZE nC
, SCSIZE nR
) const override
;
520 /// @return 0.0 if empty or empty path, else value or DoubleError.
521 virtual double GetDouble( SCSIZE nC
, SCSIZE nR
) const override
;
522 /// @return 0.0 if empty or empty path, else value or DoubleError.
523 virtual double GetDouble( SCSIZE nIndex
) const override
;
524 /// @return value or DoubleError or string converted to value.
525 virtual double GetDoubleWithStringConversion( SCSIZE nC
, SCSIZE nR
) const override
;
527 /// @return empty string if empty or empty path, else string content.
528 virtual svl::SharedString
GetString( SCSIZE nC
, SCSIZE nR
) const override
;
529 /// @return empty string if empty or empty path, else string content.
530 virtual svl::SharedString
GetString( SCSIZE nIndex
) const override
;
532 /** @returns the matrix element's string if one is present, otherwise the
533 numerical value formatted as string, or in case of an error the error
534 string is returned; an empty string for empty, a "FALSE" string for
536 virtual svl::SharedString
GetString( SvNumberFormatter
& rFormatter
, SCSIZE nC
, SCSIZE nR
) const override
;
538 /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
540 virtual ScMatrixValue
Get( SCSIZE nC
, SCSIZE nR
) const override
;
542 /// @return <TRUE/> if string or empty or empty path, in fact non-value.
543 virtual bool IsString( SCSIZE nIndex
) const override
;
545 /// @return <TRUE/> if string or empty or empty path, in fact non-value.
546 virtual bool IsString( SCSIZE nC
, SCSIZE nR
) const override
;
548 /// @return <TRUE/> if empty or empty cell or empty result, not empty path.
549 virtual bool IsEmpty( SCSIZE nC
, SCSIZE nR
) const override
;
551 /// @return <TRUE/> if empty cell, not empty or empty result or empty path.
552 virtual bool IsEmptyCell( SCSIZE nC
, SCSIZE nR
) const override
;
554 /// @return <TRUE/> if empty result, not empty or empty cell or empty path.
555 virtual bool IsEmptyResult( SCSIZE nC
, SCSIZE nR
) const override
;
557 /// @return <TRUE/> if empty path, not empty or empty cell or empty result.
558 virtual bool IsEmptyPath( SCSIZE nC
, SCSIZE nR
) const override
;
560 /// @return <TRUE/> if value or boolean.
561 virtual bool IsValue( SCSIZE nIndex
) const override
;
563 /// @return <TRUE/> if value or boolean.
564 virtual bool IsValue( SCSIZE nC
, SCSIZE nR
) const override
;
566 /// @return <TRUE/> if value or boolean or empty or empty path.
567 virtual bool IsValueOrEmpty( SCSIZE nC
, SCSIZE nR
) const override
;
569 /// @return <TRUE/> if boolean.
570 virtual bool IsBoolean( SCSIZE nC
, SCSIZE nR
) const override
;
572 /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties
573 virtual bool IsNumeric() const override
;
575 virtual void MatTrans( ScMatrix
& mRes
) const override
;
576 virtual void MatCopy ( ScMatrix
& mRes
) const override
;
578 // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values
579 virtual void CompareEqual() override
;
580 virtual void CompareNotEqual() override
;
581 virtual void CompareLess() override
;
582 virtual void CompareGreater() override
;
583 virtual void CompareLessEqual() override
;
584 virtual void CompareGreaterEqual() override
;
586 virtual double And() const override
; // logical AND of all matrix values, or NAN
587 virtual double Or() const override
; // logical OR of all matrix values, or NAN
588 virtual double Xor() const override
; // logical XOR of all matrix values, or NAN
590 virtual IterateResult
Sum(bool bTextAsZero
) const override
;
591 virtual IterateResult
SumSquare(bool bTextAsZero
) const override
;
592 virtual IterateResult
Product(bool bTextAsZero
) const override
;
593 virtual size_t Count(bool bCountStrings
, bool bCountErrors
) const override
;
594 virtual size_t MatchDoubleInColumns(double fValue
, size_t nCol1
, size_t nCol2
) const override
;
595 virtual size_t MatchStringInColumns(const svl::SharedString
& rStr
, size_t nCol1
, size_t nCol2
) const override
;
597 virtual double GetMaxValue( bool bTextAsZero
) const override
;
598 virtual double GetMinValue( bool bTextAsZero
) const override
;
600 virtual ScMatrixRef
CompareMatrix(
601 sc::Compare
& rComp
, size_t nMatPos
, sc::CompareOptions
* pOptions
= nullptr ) const override
;
604 * Convert the content of matrix into a linear array of numeric values.
605 * String elements are mapped to NaN's and empty elements are mapped to
606 * either NaN or zero values.
608 * @param bEmptyAsZero if true empty elements are mapped to zero values,
609 * otherwise they become NaN values.
611 virtual void GetDoubleArray( std::vector
<double>& rArray
, bool bEmptyAsZero
= true ) const override
;
612 virtual void MergeDoubleArray( std::vector
<double>& rArray
, Op eOp
) const override
;
614 virtual void NotOp(ScMatrix
& rMat
) override
;
615 virtual void NegOp(ScMatrix
& rMat
) override
;
616 virtual void AddOp(double fVal
, ScMatrix
& rMat
) override
;
617 virtual void SubOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
618 virtual void MulOp(double fVal
, ScMatrix
& rMat
) override
;
619 virtual void DivOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
620 virtual void PowOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
622 virtual std::vector
<ScMatrix::IterateResult
> Collect(bool bTextAsZero
, const std::vector
<std::unique_ptr
<sc::op::Op
>>& aOp
) override
;
624 virtual void ExecuteOperation(const std::pair
<size_t, size_t>& rStartPos
, const std::pair
<size_t, size_t>& rEndPos
,
625 DoubleOpFunction aDoubleFunc
, BoolOpFunction aBoolFunc
, StringOpFunction aStringFunc
,
626 EmptyOpFunction aEmptyFunc
) const override
;
627 ScFullMatrix
& operator+= ( const ScFullMatrix
& r
);
629 virtual void MatConcat(SCSIZE nMaxCol
, SCSIZE nMaxRow
, const ScMatrixRef
& xMat1
, const ScMatrixRef
& xMat2
,
630 SvNumberFormatter
& rFormatter
, svl::SharedStringPool
& rPool
) override
;
633 virtual void Dump() const override
;
637 class SC_DLLPUBLIC ScVectorRefMatrix
: public ScMatrix
639 const formula::DoubleVectorRefToken
* mpToken
;
640 ScInterpreter
* mpErrorInterpreter
;
642 /// For the operations that are not fully implemented, create a ScFullMatrix, and operate on it.
643 std::unique_ptr
<ScFullMatrix
> mpFullMatrix
;
648 ScVectorRefMatrix( const ScVectorRefMatrix
& ) = delete;
649 ScVectorRefMatrix
& operator=( const ScVectorRefMatrix
&) = delete;
651 /// For the operations that are not fully implemented, create a ScFullMatrix, and operate on it.
653 /// Note: This is potentially an expensive operation.
654 /// TODO: Implement as much as possible directly using the DoubleVectorRefToken.
655 void ensureFullMatrix();
659 ScVectorRefMatrix(const formula::DoubleVectorRefToken
* pToken
, SCSIZE nRowStart
, SCSIZE nRowSize
);
661 virtual ~ScVectorRefMatrix();
663 /** Clone the matrix. */
664 virtual ScMatrix
* Clone() const override
;
667 * Resize the matrix to specified new dimension.
669 virtual void Resize(SCSIZE nC
, SCSIZE nR
) override
;
671 virtual void Resize(SCSIZE nC
, SCSIZE nR
, double fVal
) override
;
673 /** Clone the matrix and extend it to the new size. nNewCols and nNewRows
674 MUST be at least of the size of the original matrix. */
675 virtual ScMatrix
* CloneAndExtend(SCSIZE nNewCols
, SCSIZE nNewRows
) const override
;
677 virtual void SetErrorInterpreter(ScInterpreter
* p
) override
;
678 virtual void GetDimensions(SCSIZE
& rC
, SCSIZE
& rR
) const override
;
679 virtual SCSIZE
GetElementCount() const override
;
680 virtual bool ValidColRow( SCSIZE nC
, SCSIZE nR
) const override
;
682 /** For a row vector or column vector, if the position does not point into
683 the vector but is a valid column or row offset it is adapted such that
684 it points to an element to be replicated, same column row 0 for a row
685 vector, same row column 0 for a column vector. Else, for a 2D matrix,
688 virtual bool ValidColRowReplicated(SCSIZE
& rC
, SCSIZE
& rR
) const override
;
690 /** Checks if the matrix position is within the matrix. If it is not, for a
691 row vector or column vector the position is adapted such that it points
692 to an element to be replicated, same column row 0 for a row vector,
693 same row column 0 for a column vector. Else, for a 2D matrix and
694 position not within matrix, returns false.
696 virtual bool ValidColRowOrReplicated(SCSIZE
& rC
, SCSIZE
& rR
) const override
;
698 virtual void PutDouble(double fVal
, SCSIZE nC
, SCSIZE nR
) override
;
699 virtual void PutDouble(double fVal
, SCSIZE nIndex
) override
;
700 virtual void PutDouble(const double* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) override
;
702 virtual void PutString(const svl::SharedString
& rStr
, SCSIZE nC
, SCSIZE nR
) override
;
703 virtual void PutString(const svl::SharedString
& rStr
, SCSIZE nIndex
) override
;
704 virtual void PutString(const svl::SharedString
* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) override
;
706 virtual void PutEmpty(SCSIZE nC
, SCSIZE nR
) override
;
708 /// Jump sal_False without path
709 virtual void PutEmptyPath(SCSIZE nC
, SCSIZE nR
) override
;
710 virtual void PutError(sal_uInt16 nErrorCode
, SCSIZE nC
, SCSIZE nR
) override
;
711 virtual void PutBoolean(bool bVal
, SCSIZE nC
, SCSIZE nR
) override
;
713 virtual void FillDouble(double fVal
, SCSIZE nC1
, SCSIZE nR1
, SCSIZE nC2
, SCSIZE nR2
) override
;
715 /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */
716 virtual void PutDoubleVector(const ::std::vector
< double > & rVec
, SCSIZE nC
, SCSIZE nR
) override
;
718 /** Put a column vector of strings, starting at row nR, must fit into dimensions. */
719 virtual void PutStringVector(const ::std::vector
< svl::SharedString
> & rVec
, SCSIZE nC
, SCSIZE nR
) override
;
721 /** Put a column vector of empties, starting at row nR, must fit into dimensions. */
722 virtual void PutEmptyVector(SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
724 /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */
725 virtual void PutEmptyResultVector(SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
727 /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */
728 virtual void PutEmptyPathVector(SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
730 /** May be used before obtaining the double value of an element to avoid
731 passing its NAN around.
732 @ATTENTION: MUST NOT be used if the element is a string!
733 Use GetErrorIfNotString() instead if not sure.
734 @returns 0 if no error, else one of err... constants */
735 virtual sal_uInt16
GetError(SCSIZE nC
, SCSIZE nR
) const override
;
737 /// @return 0.0 if empty or empty path, else value or DoubleError.
738 virtual double GetDouble(SCSIZE nC
, SCSIZE nR
) const override
;
739 /// @return 0.0 if empty or empty path, else value or DoubleError.
740 virtual double GetDouble(SCSIZE nIndex
) const override
;
741 /// @return value or DoubleError or string converted to value.
742 virtual double GetDoubleWithStringConversion( SCSIZE nC
, SCSIZE nR
) const override
;
744 /// @return empty string if empty or empty path, else string content.
745 virtual svl::SharedString
GetString(SCSIZE nC
, SCSIZE nR
) const override
;
746 /// @return empty string if empty or empty path, else string content.
747 virtual svl::SharedString
GetString(SCSIZE nIndex
) const override
;
749 /** @returns the matrix element's string if one is present, otherwise the
750 numerical value formatted as string, or in case of an error the error
751 string is returned; an empty string for empty, a "FALSE" string for
753 virtual svl::SharedString
GetString(SvNumberFormatter
& rFormatter
, SCSIZE nC
, SCSIZE nR
) const override
;
755 /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
757 virtual ScMatrixValue
Get(SCSIZE nC
, SCSIZE nR
) const override
;
759 /// @return <TRUE/> if string or empty or empty path, in fact non-value.
760 virtual bool IsString(SCSIZE nIndex
) const override
;
762 /// @return <TRUE/> if string or empty or empty path, in fact non-value.
763 virtual bool IsString(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
;
817 virtual ScMatrixRef
CompareMatrix(sc::Compare
& rComp
, size_t nMatPos
, sc::CompareOptions
* pOptions
= nullptr) const override
;
820 * Convert the content of matrix into a linear array of numeric values.
821 * String elements are mapped to NaN's and empty elements are mapped to
822 * either NaN or zero values.
824 * @param bEmptyAsZero if true empty elements are mapped to zero values,
825 * otherwise they become NaN values.
827 virtual void GetDoubleArray(std::vector
<double>& rVector
, bool bEmptyAsZero
= true) const override
;
828 virtual void MergeDoubleArray(std::vector
<double>& rVector
, Op eOp
) const override
;
830 virtual void NotOp(ScMatrix
& rMat
) override
;
831 virtual void NegOp(ScMatrix
& rMat
) override
;
832 virtual void AddOp(double fVal
, ScMatrix
& rMat
) override
;
833 virtual void SubOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
834 virtual void MulOp(double fVal
, ScMatrix
& rMat
) override
;
835 virtual void DivOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
836 virtual void PowOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
838 virtual std::vector
<ScMatrix::IterateResult
> Collect(bool bTextAsZero
, const std::vector
<std::unique_ptr
<sc::op::Op
>>& aOp
) override
;
840 virtual void ExecuteOperation(const std::pair
<size_t, size_t>& rStartPos
, const std::pair
<size_t, size_t>& rEndPos
,
841 DoubleOpFunction aDoubleFunc
, BoolOpFunction aBoolFunc
, StringOpFunction aStringFunc
,
842 EmptyOpFunction aEmptyFunc
) const override
;
844 ScVectorRefMatrix
& operator+=(const ScVectorRefMatrix
& r
);
846 virtual void MatConcat(SCSIZE nMaxCol
, SCSIZE nMaxRow
, const ScMatrixRef
& xMat1
, const ScMatrixRef
& xMat2
,
847 SvNumberFormatter
& rFormatter
, svl::SharedStringPool
& rPool
) override
;
850 virtual void Dump() const override
856 inline void intrusive_ptr_add_ref(const ScMatrix
* p
)
861 inline void intrusive_ptr_release(const ScMatrix
* p
)
866 #endif // INCLUDED_SC_INC_SCMATRIX_HXX
868 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */