bump product version to 4.1.6.2
[LibreOffice.git] / sc / inc / scmatrix.hxx
blobc91b0ca8bdb9c23c6e18ff17c89b41e57b27884d
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 SC_MATRIX_HXX
21 #define SC_MATRIX_HXX
23 #include "global.hxx"
24 #include "types.hxx"
25 #include "formula/errorcodes.hxx"
26 #include "scdllapi.h"
27 #include <rtl/ustring.hxx>
29 #include <boost/intrusive_ptr.hpp>
31 class ScInterpreter;
32 class SvNumberFormatter;
33 class ScMatrixImpl;
35 typedef sal_uInt8 ScMatValType;
36 const ScMatValType SC_MATVAL_VALUE = 0x00;
37 const ScMatValType SC_MATVAL_BOOLEAN = 0x01;
38 const ScMatValType SC_MATVAL_STRING = 0x02;
39 const ScMatValType SC_MATVAL_EMPTY = SC_MATVAL_STRING | 0x04; // STRING plus flag
40 const ScMatValType SC_MATVAL_EMPTYPATH = SC_MATVAL_EMPTY | 0x08; // EMPTY plus flag
41 const ScMatValType SC_MATVAL_NONVALUE = SC_MATVAL_EMPTYPATH; // mask of all non-value bits
43 /**
44 * Try NOT to use this struct. This struct should go away in a hopefully
45 * not so distant futture.
47 struct ScMatrixValue
49 double fVal;
50 OUString aStr;
51 ScMatValType nType;
53 /// Only valid if ScMatrix methods indicate so!
54 const OUString& GetString() const { return aStr; }
56 /// Only valid if ScMatrix methods indicate that this is no string!
57 sal_uInt16 GetError() const { return GetDoubleErrorValue( fVal); }
59 /// Only valid if ScMatrix methods indicate that this is a boolean
60 bool GetBoolean() const { return fVal != 0.0; }
62 ScMatrixValue() : fVal(0.0), nType(SC_MATVAL_EMPTY) {}
64 ScMatrixValue(const ScMatrixValue& r) :
65 fVal(r.fVal), aStr(r.aStr), nType(r.nType) {}
67 bool operator== (const ScMatrixValue& r) const
69 if (nType != r.nType)
70 return false;
72 switch (nType)
74 case SC_MATVAL_VALUE:
75 case SC_MATVAL_BOOLEAN:
76 return fVal == r.fVal;
77 break;
78 default:
82 return aStr == r.aStr;
85 bool operator!= (const ScMatrixValue& r) const
87 return !operator==(r);
90 ScMatrixValue& operator= (const ScMatrixValue& r)
92 if (this == &r)
93 return *this;
95 nType = r.nType;
96 fVal = r.fVal;
97 aStr = r.aStr;
98 return *this;
103 * Matrix data type that can store values of mixed types. Each element can
104 * be one of the following types: numeric, string, boolean, empty, and empty
105 * path.
107 class SC_DLLPUBLIC ScMatrix
109 ScMatrixImpl* pImpl;
110 mutable size_t nRefCnt; // reference count
112 // only delete via Delete()
113 ~ScMatrix();
115 // not implemented, prevent usage
116 ScMatrix( const ScMatrix& );
117 ScMatrix& operator=( const ScMatrix&);
119 public:
121 * When adding all numerical matrix elements for a scalar result such as
122 * summation, the interpreter wants to separate the first non-zero value
123 * with the rest of the summed values.
125 * TODO: Find out if we still need to do this. If not, we can re-write
126 * ScInterpreter::IterateParameters() to make it simpler and remove this
127 * struct.
129 struct IterateResult
131 double mfFirst;
132 double mfRest;
133 size_t mnCount;
135 IterateResult(double fFirst, double fRest, size_t nCount) :
136 mfFirst(fFirst), mfRest(fRest), mnCount(nCount) {}
138 IterateResult(const IterateResult& r) :
139 mfFirst(r.mfFirst), mfRest(r.mfRest), mnCount(r.mnCount) {}
142 /// The maximum number of elements a matrix may have at runtime.
143 inline static size_t GetElementsMax()
145 // TODO: Fix me.
146 return 0x08000000;
147 #if 0
148 // Roughly 125MB in total, divided by 8+1 per element => 14M elements.
149 const size_t nMemMax = 0x08000000 / (sizeof(ScMatrixValue) + sizeof(ScMatValType));
150 // With MAXROWCOUNT==65536 and 128 columns => 8M elements ~72MB.
151 const size_t nArbitraryLimit = (size_t)MAXROWCOUNT * 128;
152 // Stuffed with a million rows would limit this to 14 columns.
153 return nMemMax < nArbitraryLimit ? nMemMax : nArbitraryLimit;
154 #endif
157 /// Value or boolean.
158 inline static bool IsValueType( ScMatValType nType )
160 return nType <= SC_MATVAL_BOOLEAN;
163 /// Boolean.
164 inline static bool IsBooleanType( ScMatValType nType )
166 return nType == SC_MATVAL_BOOLEAN;
169 /// String, empty or empty path, but not value nor boolean.
170 inline static bool IsNonValueType( ScMatValType nType )
172 return (nType & SC_MATVAL_NONVALUE) != 0;
175 /** String, but not empty or empty path or any other type.
176 Not named IsStringType to prevent confusion because previously
177 IsNonValueType was named IsStringType. */
178 inline static bool IsRealStringType( ScMatValType nType )
180 return (nType & SC_MATVAL_NONVALUE) == SC_MATVAL_STRING;
183 /// Empty, but not empty path or any other type.
184 inline static bool IsEmptyType( ScMatValType nType )
186 return (nType & SC_MATVAL_NONVALUE) == SC_MATVAL_EMPTY;
189 /// Empty path, but not empty or any other type.
190 inline static bool IsEmptyPathType( ScMatValType nType )
192 return (nType & SC_MATVAL_NONVALUE) == SC_MATVAL_EMPTYPATH;
195 ScMatrix(SCSIZE nC, SCSIZE nR);
196 ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal);
198 /** Clone the matrix. */
199 ScMatrix* Clone() const;
201 /** Clone the matrix if mbCloneIfConst (immutable) is set, otherwise
202 return _this_ matrix, to be assigned to a ScMatrixRef. */
203 ScMatrix* CloneIfConst();
205 /** Set the matrix to (im)mutable for CloneIfConst(), only the interpreter
206 should do this and know the consequences. */
207 void SetImmutable( bool bVal );
210 * Resize the matrix to specified new dimension.
212 void Resize( SCSIZE nC, SCSIZE nR);
214 void Resize(SCSIZE nC, SCSIZE nR, double fVal);
216 /** Clone the matrix and extend it to the new size. nNewCols and nNewRows
217 MUST be at least of the size of the original matrix. */
218 ScMatrix* CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const;
220 inline void IncRef() const
222 ++nRefCnt;
224 inline void DecRef() const
226 --nRefCnt;
227 if (nRefCnt == 0)
228 delete this;
231 void SetErrorInterpreter( ScInterpreter* p);
232 void GetDimensions( SCSIZE& rC, SCSIZE& rR) const;
233 SCSIZE GetElementCount() const;
234 bool ValidColRow( SCSIZE nC, SCSIZE nR) const;
235 SCSIZE CalcOffset( SCSIZE nC, SCSIZE nR) const;
237 /** For a row vector or column vector, if the position does not point into
238 the vector but is a valid column or row offset it is adapted such that
239 it points to an element to be replicated, same column row 0 for a row
240 vector, same row column 0 for a column vector. Else, for a 2D matrix,
241 returns false.
243 bool ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const;
245 /** Checks if the matrix position is within the matrix. If it is not, for a
246 row vector or column vector the position is adapted such that it points
247 to an element to be replicated, same column row 0 for a row vector,
248 same row column 0 for a column vector. Else, for a 2D matrix and
249 position not within matrix, returns false.
251 bool ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const;
253 void PutDouble( double fVal, SCSIZE nC, SCSIZE nR);
254 void PutDouble( double fVal, SCSIZE nIndex);
255 void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
257 void PutString( const OUString& rStr, SCSIZE nC, SCSIZE nR);
258 void PutString( const OUString& rStr, SCSIZE nIndex);
259 void PutString(const OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
261 void PutEmpty( SCSIZE nC, SCSIZE nR);
263 /// Jump sal_False without path
264 void PutEmptyPath( SCSIZE nC, SCSIZE nR);
265 void PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR );
266 void PutBoolean( bool bVal, SCSIZE nC, SCSIZE nR);
268 void FillDouble( double fVal,
269 SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 );
271 /** May be used before obtaining the double value of an element to avoid
272 passing its NAN around.
273 @ATTENTION: MUST NOT be used if the element is a string!
274 Use GetErrorIfNotString() instead if not sure.
275 @returns 0 if no error, else one of err... constants */
276 sal_uInt16 GetError( SCSIZE nC, SCSIZE nR) const;
278 /** Use in ScInterpreter to obtain the error code, if any.
279 @returns 0 if no error or string element, else one of err... constants */
280 sal_uInt16 GetErrorIfNotString( SCSIZE nC, SCSIZE nR) const
281 { return IsValue( nC, nR) ? GetError( nC, nR) : 0; }
283 /// @return 0.0 if empty or empty path, else value or DoubleError.
284 double GetDouble( SCSIZE nC, SCSIZE nR) const;
285 /// @return 0.0 if empty or empty path, else value or DoubleError.
286 double GetDouble( SCSIZE nIndex) const;
288 /// @return empty string if empty or empty path, else string content.
289 OUString GetString( SCSIZE nC, SCSIZE nR) const;
290 /// @return empty string if empty or empty path, else string content.
291 OUString GetString( SCSIZE nIndex) const;
293 /** @returns the matrix element's string if one is present, otherwise the
294 numerical value formatted as string, or in case of an error the error
295 string is returned; an empty string for empty, a "FALSE" string for
296 empty path. */
297 OUString GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const;
299 /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
300 /// an empty string!
301 ScMatrixValue Get( SCSIZE nC, SCSIZE nR) const;
303 /// @return <TRUE/> if string or empty or empty path, in fact non-value.
304 sal_Bool IsString( SCSIZE nIndex ) const;
306 /// @return <TRUE/> if string or empty or empty path, in fact non-value.
307 sal_Bool IsString( SCSIZE nC, SCSIZE nR ) const;
309 /// @return <TRUE/> if empty or empty path.
310 sal_Bool IsEmpty( SCSIZE nC, SCSIZE nR ) const;
312 /// @return <TRUE/> if empty path.
313 sal_Bool IsEmptyPath( SCSIZE nC, SCSIZE nR ) const;
315 /// @return <TRUE/> if value or boolean.
316 sal_Bool IsValue( SCSIZE nIndex ) const;
318 /// @return <TRUE/> if value or boolean.
319 sal_Bool IsValue( SCSIZE nC, SCSIZE nR ) const;
321 /// @return <TRUE/> if value or boolean or empty or empty path.
322 sal_Bool IsValueOrEmpty( SCSIZE nC, SCSIZE nR ) const;
324 /// @return <TRUE/> if boolean.
325 sal_Bool IsBoolean( SCSIZE nC, SCSIZE nR ) const;
327 /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties
328 sal_Bool IsNumeric() const;
330 void MatTrans( ScMatrix& mRes) const;
331 void MatCopy ( ScMatrix& mRes) const;
333 // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values
334 void CompareEqual();
335 void CompareNotEqual();
336 void CompareLess();
337 void CompareGreater();
338 void CompareLessEqual();
339 void CompareGreaterEqual();
341 double And() const; // logical AND of all matrix values, or NAN
342 double Or() const; // logical OR of all matrix values, or NAN
343 double Xor() const; // logical XOR of all matrix values, or NAN
345 IterateResult Sum(bool bTextAsZero) const;
346 IterateResult SumSquare(bool bTextAsZero) const;
347 IterateResult Product(bool bTextAsZero) const;
348 size_t Count(bool bCountStrings) const;
350 // All other matrix functions MatMult, MInv, ... are in ScInterpreter
351 // to be numerically safe.
354 inline void intrusive_ptr_add_ref(const ScMatrix* p)
356 p->IncRef();
359 inline void intrusive_ptr_release(const ScMatrix* p)
361 p->DecRef();
364 #endif // SC_MATRIX_HXX
366 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */