/src/libreoffice/scaddins/source/analysis/analysishelper.hxx
Line | Count | Source |
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 | | #pragma once |
20 | | |
21 | | |
22 | | #include <com/sun/star/uno/Reference.hxx> |
23 | | #include <unotools/resmgr.hxx> |
24 | | |
25 | | #include <cmath> |
26 | | #include <complex> |
27 | | |
28 | | #include <memory> |
29 | | #include <vector> |
30 | | |
31 | | namespace com::sun::star::beans { class XPropertySet; } |
32 | | namespace com::sun::star::uno { class XComponentContext; } |
33 | | namespace com::sun::star::util { class XNumberFormatter2; } |
34 | | |
35 | | namespace sca::analysis { |
36 | | |
37 | | class ScaAnyConverter; |
38 | | |
39 | | inline bool IsLeapYear( sal_uInt16 nYear ); |
40 | | |
41 | | #ifdef DISABLE_DYNLOADING |
42 | | |
43 | | // Avoid clash with the functions with same name in |
44 | | // scaddins/source/datefunc/datefunc.cxx. I am not sure if each pair |
45 | | // have identical semantics, but if yes, one copy should be enough, |
46 | | // but what would be a suitable library where such functions could go? |
47 | | // Or can the analysis library depend on the date library or the other |
48 | | // way around? |
49 | | |
50 | 277 | #define DaysInMonth analysishelper_DaysInMonth |
51 | 17 | #define DateToDays analysishelper_DateToDays |
52 | 15 | #define DaysToDate analysishelper_DaysToDate |
53 | 14 | #define GetNullDate analysishelper_GetNullDate |
54 | | |
55 | | #endif |
56 | | |
57 | | sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear ); |
58 | | sal_Int32 DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear ); |
59 | | /// @throws css::lang::IllegalArgumentException |
60 | | void DaysToDate( sal_Int32 nDays, sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear ); |
61 | | /// @throws css::uno::RuntimeException |
62 | | sal_Int32 GetNullDate( const css::uno::Reference< css::beans::XPropertySet >& xOptions ); |
63 | | sal_Int32 GetDiffDate360( |
64 | | sal_uInt16 nDay1, sal_uInt16 nMonth1, sal_uInt16 nYear1, bool bLeapYear1, |
65 | | sal_uInt16 nDay2, sal_uInt16 nMonth2, sal_uInt16 nYear2, |
66 | | bool bUSAMethod ); |
67 | | inline sal_Int32 GetDiffDate360( const css::uno::Reference< css::beans::XPropertySet >& xOpt, sal_Int32 nDate1, sal_Int32 nDate2, bool bUSAMethod ); |
68 | | sal_Int32 GetDiffDate360( sal_Int32 nNullDate, sal_Int32 nDate1, sal_Int32 nDate2, bool bUSAMethod ); |
69 | | |
70 | | sal_Int32 GetDaysInYears( sal_uInt16 nYear1, sal_uInt16 nYear2 ); |
71 | | inline sal_Int16 GetDayOfWeek( sal_Int32 nDate ); |
72 | | /// @throws css::uno::RuntimeException |
73 | | /// @throws css::lang::IllegalArgumentException |
74 | | sal_Int32 GetDiffDate( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode, |
75 | | sal_Int32* pOptDaysIn1stYear ); |
76 | | /// @throws css::uno::RuntimeException |
77 | | /// @throws css::lang::IllegalArgumentException |
78 | | double GetYearDiff( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ); |
79 | | /// @throws css::uno::RuntimeException |
80 | | /// @throws css::lang::IllegalArgumentException |
81 | | sal_Int32 GetDaysInYear( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nMode ); |
82 | | /// @throws css::uno::RuntimeException |
83 | | /// @throws css::lang::IllegalArgumentException |
84 | | double GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ); |
85 | | /// @throws css::uno::RuntimeException |
86 | | /// @throws css::lang::IllegalArgumentException |
87 | | inline double GetYearFrac( const css::uno::Reference< css::beans::XPropertySet >& xOpt, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ); |
88 | | |
89 | | double BinomialCoefficient( double n, double k ); |
90 | | double GetGcd( double f1, double f2 ); |
91 | | /// @throws css::uno::RuntimeException |
92 | | /// @throws css::lang::IllegalArgumentException |
93 | | double ConvertToDec( const OUString& rFromNum, sal_uInt16 nBaseFrom, sal_uInt16 nCharLim ); |
94 | | /// @throws css::uno::RuntimeException |
95 | | /// @throws css::lang::IllegalArgumentException |
96 | | OUString ConvertFromDec( |
97 | | double fNum, double fMin, double fMax, sal_uInt16 nBase, |
98 | | sal_Int32 nPlaces, sal_Int32 nMaxPlaces, bool bUsePlaces ); |
99 | | double Erf( double fX ); |
100 | | double Erfc( double fX ); |
101 | | bool ParseDouble( const sal_Unicode*& rpDoubleAsString, double& rReturn ); |
102 | | OUString GetString( double fNumber, bool bLeadingSign, sal_uInt16 nMaxNumOfDigits = 15 ); |
103 | | |
104 | | /// @throws css::uno::RuntimeException |
105 | | /// @throws css::lang::IllegalArgumentException |
106 | | double GetAmordegrc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, |
107 | | double fRestVal, double fPer, double fRate, sal_Int32 nBase ); |
108 | | /// @throws css::uno::RuntimeException |
109 | | /// @throws css::lang::IllegalArgumentException |
110 | | double GetAmorlinc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, |
111 | | double fRestVal, double fPer, double fRate, sal_Int32 nBase ); |
112 | | /// @throws css::uno::RuntimeException |
113 | | /// @throws css::lang::IllegalArgumentException |
114 | | double GetDuration( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, |
115 | | double fYield, sal_Int32 nFreq, sal_Int32 nBase ); |
116 | | /// @throws css::uno::RuntimeException |
117 | | /// @throws css::lang::IllegalArgumentException |
118 | | double GetYieldmat( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, |
119 | | double fRate, double fPrice, sal_Int32 nBase ); |
120 | | /// @throws css::uno::RuntimeException |
121 | | /// @throws css::lang::IllegalArgumentException |
122 | | double GetOddfprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, |
123 | | sal_Int32 nFirstCoup, double fRate, double fYield, double fRedemp, |
124 | | sal_Int32 nFreq, sal_Int32 nBase ); |
125 | | /// @throws css::uno::RuntimeException |
126 | | /// @throws css::lang::IllegalArgumentException |
127 | | double getYield_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fPrice, |
128 | | double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ); |
129 | | /// @throws css::uno::RuntimeException |
130 | | /// @throws css::lang::IllegalArgumentException |
131 | | double getPrice_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield, |
132 | | double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ); |
133 | | /// @throws css::uno::RuntimeException |
134 | | /// @throws css::lang::IllegalArgumentException |
135 | | double GetOddfyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, |
136 | | sal_Int32 nFirstCoup, double fRate, double fPrice, double fRedemp, |
137 | | sal_Int32 nFreq, sal_Int32 nBase ); |
138 | | /// @throws css::uno::RuntimeException |
139 | | /// @throws css::lang::IllegalArgumentException |
140 | | double GetOddlprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest, |
141 | | double fRate, double fYield, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ); |
142 | | /// @throws css::uno::RuntimeException |
143 | | /// @throws css::lang::IllegalArgumentException |
144 | | double GetOddlyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest, |
145 | | double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ); |
146 | | double GetPmt( double fRate, double fNper, double fPv, double fFv, sal_Int32 nPayType ); |
147 | | double GetFv( double fRate, double fNper, double fPmt, double fPv, sal_Int32 nPayType ); |
148 | | |
149 | | /// @throws css::uno::RuntimeException |
150 | | /// @throws css::lang::IllegalArgumentException |
151 | | double GetCouppcd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, |
152 | | sal_Int32 nBase ); |
153 | | /// @throws css::uno::RuntimeException |
154 | | /// @throws css::lang::IllegalArgumentException |
155 | | double GetCoupncd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, |
156 | | sal_Int32 nBase ); |
157 | | /// @throws css::uno::RuntimeException |
158 | | /// @throws css::lang::IllegalArgumentException |
159 | | double GetCoupdaybs( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, |
160 | | sal_Int32 nBase ); |
161 | | /// @throws css::uno::RuntimeException |
162 | | /// @throws css::lang::IllegalArgumentException |
163 | | double GetCoupdaysnc( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, |
164 | | sal_Int32 nBase ); |
165 | | |
166 | | /// @throws css::uno::RuntimeException |
167 | | /// @throws css::lang::IllegalArgumentException |
168 | | double GetCoupnum( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, |
169 | | sal_Int32 nFreq, sal_Int32 nBase ); |
170 | | /// @throws css::uno::RuntimeException |
171 | | /// @throws css::lang::IllegalArgumentException |
172 | | double GetCoupdays( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, |
173 | | sal_Int32 nBase ); |
174 | | |
175 | | |
176 | | enum class FDCategory |
177 | | { |
178 | | DateTime, |
179 | | Finance, |
180 | | Inf, |
181 | | Math, |
182 | | Tech |
183 | | }; |
184 | | |
185 | | |
186 | | struct FuncDataBase |
187 | | { |
188 | | const char* pIntName; |
189 | | TranslateId pUINameID; // resource ID to UI name |
190 | | const TranslateId* pDescrID; // resource ID to description, parameter names and ~ description |
191 | | bool bDouble; // name already exist in Calc |
192 | | bool bWithOpt; // first parameter is internal |
193 | | const char* const* pCompListID; // list of valid names |
194 | | sal_uInt16 nNumOfParams; // number of named / described parameters |
195 | | FDCategory eCat; // function category |
196 | | const char* pSuffix; // if bDouble, append a suffix other than "_ADD" for UI |
197 | | }; |
198 | | |
199 | | |
200 | | class FuncData final |
201 | | { |
202 | | private: |
203 | | OUString aIntName; |
204 | | TranslateId pUINameID; |
205 | | const TranslateId* pDescrID; // leads also to parameter descriptions! |
206 | | bool bDouble; // flag for names that already exist in Calc |
207 | | bool bWithOpt; // has internal parameter on first position |
208 | | |
209 | | sal_uInt16 nParam; // num of parameters |
210 | | std::vector<OUString> aCompList; // list of all valid names |
211 | | FDCategory eCat; // function category |
212 | | OUString aSuffix; // if bDouble and not empty, append a suffix other than "_ADD" for UI |
213 | | |
214 | | public: |
215 | | FuncData(const FuncDataBase& rBaseData); |
216 | | |
217 | | inline const TranslateId& GetUINameID() const; |
218 | | inline const TranslateId* GetDescrID() const; |
219 | | inline bool IsDouble() const; |
220 | | inline const OUString& GetSuffix() const; |
221 | | |
222 | | sal_uInt16 GetStrIndex( sal_uInt16 nParamNum ) const; |
223 | | inline bool Is( std::u16string_view rCompareTo ) const; |
224 | | |
225 | | inline const std::vector<OUString> & |
226 | | GetCompNameList() const; |
227 | | |
228 | | inline FDCategory GetCategory() const; |
229 | | }; |
230 | | |
231 | | typedef std::vector< FuncData > FuncDataList; |
232 | | |
233 | | void InitFuncDataList(FuncDataList& rList); |
234 | | |
235 | | // Predicate for use with std::find_if |
236 | | struct FindFuncData |
237 | | { |
238 | | const OUString& m_rId; |
239 | 5.13k | explicit FindFuncData( const OUString& rId ) : m_rId(rId) {} |
240 | 295k | bool operator() ( FuncData const & rCandidate ) const { return rCandidate.Is(m_rId); } |
241 | | }; |
242 | | |
243 | | /// sorted list with unique sal_Int32 values |
244 | | class SortedIndividualInt32List final |
245 | | { |
246 | | private: |
247 | | std::vector<sal_Int32> maVector; |
248 | | |
249 | | void Insert( sal_Int32 nDay ); |
250 | | void Insert( sal_Int32 nDay, sal_Int32 nNullDate, bool bInsertOnWeekend ); |
251 | | /// @throws css::uno::RuntimeException |
252 | | /// @throws css::lang::IllegalArgumentException |
253 | | void Insert( double fDay, sal_Int32 nNullDate, bool bInsertOnWeekend ); |
254 | | |
255 | | /** @param rAnyConv must be an initialized ScaAnyConmverter |
256 | | @param bInsertOnWeekend insertion mode: false = holidays on weekend are omitted |
257 | | @throws css::uno::RuntimeException |
258 | | @throws css::lang::IllegalArgumentException |
259 | | */ |
260 | | void InsertHolidayList( |
261 | | const ScaAnyConverter& rAnyConv, |
262 | | const css::uno::Any& rHolAny, |
263 | | sal_Int32 nNullDate, |
264 | | bool bInsertOnWeekend ); |
265 | | |
266 | | public: |
267 | | SortedIndividualInt32List(); |
268 | | ~SortedIndividualInt32List(); |
269 | | |
270 | | sal_uInt32 Count() const |
271 | 56.3k | { return maVector.size(); } |
272 | | |
273 | | /// @return element on position nIndex or 0 on invalid index |
274 | | sal_Int32 Get( sal_uInt32 n ) const |
275 | 0 | { return maVector[n]; } |
276 | | |
277 | | /// @return true if nVal (internal date representation) is contained |
278 | | bool Find( sal_Int32 nVal ) const; |
279 | | |
280 | | /** @param rAnyConv is an initialized or uninitialized ScaAnyConverter |
281 | | holidays on weekend are omitted |
282 | | @throws css::uno::RuntimeException |
283 | | @throws css::lang::IllegalArgumentException |
284 | | */ |
285 | | void InsertHolidayList( |
286 | | ScaAnyConverter& rAnyConv, |
287 | | const css::uno::Reference< css::beans::XPropertySet >& xOptions, |
288 | | const css::uno::Any& rHolAny, |
289 | | sal_Int32 nNullDate); |
290 | | }; |
291 | | |
292 | | |
293 | | class ScaDoubleList |
294 | | { |
295 | | private: |
296 | | std::vector<double> maVector; |
297 | | protected: |
298 | 60 | void ListAppend( double fValue ) { maVector.push_back(fValue); } |
299 | | |
300 | | /// @throws css::uno::RuntimeException |
301 | | /// @throws css::lang::IllegalArgumentException |
302 | | void Append( double fValue ) |
303 | 60 | { if( CheckInsert( fValue ) ) ListAppend( fValue ); } |
304 | | |
305 | | /** @param rAnyConv must be an initialized ScaAnyConmverter |
306 | | @param bIgnoreEmpty handling of empty Any's/strings: false = inserted as 0.0; true = omitted |
307 | | @throws css::uno::RuntimeException |
308 | | @throws css::lang::IllegalArgumentException |
309 | | */ |
310 | | void Append( |
311 | | const ScaAnyConverter& rAnyConv, |
312 | | const css::uno::Any& rAny, |
313 | | bool bIgnoreEmpty ); |
314 | | |
315 | | /** @param rAnyConv must be an initialized ScaAnyConmverter |
316 | | @param bIgnoreEmpty handling of empty Any's/strings: false = inserted as 0.0; true = omitted |
317 | | @throws css::uno::RuntimeException |
318 | | @throws css::lang::IllegalArgumentException |
319 | | */ |
320 | | void Append( |
321 | | const ScaAnyConverter& rAnyConv, |
322 | | const css::uno::Sequence< css::uno::Any >& rAnySeq, |
323 | | bool bIgnoreEmpty ); |
324 | | |
325 | | /** @param rAnyConv must be an initialized ScaAnyConmverter |
326 | | @param bIgnoreEmpty handling of empty Any's/strings: false = inserted as 0.0; true = omitted |
327 | | @throws css::uno::RuntimeException |
328 | | @throws css::lang::IllegalArgumentException |
329 | | */ |
330 | | void Append( |
331 | | const ScaAnyConverter& rAnyConv, |
332 | | const css::uno::Sequence< css::uno::Sequence< css::uno::Any > >& rAnySeq, |
333 | | bool bIgnoreEmpty ); |
334 | | |
335 | | public: |
336 | 12 | virtual ~ScaDoubleList() {} |
337 | | |
338 | | sal_uInt32 Count() const |
339 | 78 | { return maVector.size(); } |
340 | | double Get( sal_uInt32 n ) const |
341 | 570 | { return maVector[n]; } |
342 | | |
343 | | /// @throws css::uno::RuntimeException |
344 | | /// @throws css::lang::IllegalArgumentException |
345 | | void Append( const css::uno::Sequence< css::uno::Sequence< double > >& rValueArr ); |
346 | | /// @throws css::uno::RuntimeException |
347 | | /// @throws css::lang::IllegalArgumentException |
348 | | void Append( const css::uno::Sequence< css::uno::Sequence< sal_Int32 > >& rValueArr ); |
349 | | |
350 | | /** @param rAnyConv is an initialized or uninitialized ScaAnyConverter |
351 | | @param bIgnoreEmpty handling of empty Any's/strings: false = inserted as 0.0; true = omitted |
352 | | @throws css::uno::RuntimeException |
353 | | @throws css::lang::IllegalArgumentException |
354 | | */ |
355 | | void Append( |
356 | | ScaAnyConverter& rAnyConv, |
357 | | const css::uno::Reference< css::beans::XPropertySet >& xOpt, |
358 | | const css::uno::Sequence< css::uno::Any >& rAnySeq ); |
359 | | |
360 | | /// @throws css::uno::RuntimeException |
361 | | /// @throws css::lang::IllegalArgumentException |
362 | | virtual bool CheckInsert( double fValue ) const; |
363 | | }; |
364 | | |
365 | | |
366 | | /// stores double values >0.0, throws exception for double values <0.0, does nothing for 0.0 |
367 | | class ScaDoubleListGT0 : public ScaDoubleList |
368 | | { |
369 | | public: |
370 | | virtual bool CheckInsert( double fValue ) const override; |
371 | | }; |
372 | | |
373 | | |
374 | | /// stores double values >=0.0, throws exception for double values <0.0 |
375 | | class ScaDoubleListGE0 : public ScaDoubleList |
376 | | { |
377 | | public: |
378 | | virtual bool CheckInsert( double fValue ) const override; |
379 | | }; |
380 | | |
381 | | |
382 | | class Complex |
383 | | { |
384 | | std::complex<double> num; |
385 | | sal_Unicode c; |
386 | | |
387 | | public: |
388 | | inline Complex( double fReal, double fImag = 0.0, sal_Unicode cC = '\0' ); |
389 | | /// @throws css::uno::RuntimeException |
390 | | /// @throws css::lang::IllegalArgumentException |
391 | | explicit Complex( const OUString& rComplexAsString ); |
392 | | |
393 | | inline static bool IsImagUnit( sal_Unicode c ); |
394 | | static bool ParseString( const OUString& rComplexAsString, Complex& rReturn ); |
395 | | /// @throws css::uno::RuntimeException |
396 | | /// @throws css::lang::IllegalArgumentException |
397 | | OUString GetString() const; |
398 | | |
399 | | inline double Real() const; |
400 | | inline double Imag() const; |
401 | | |
402 | | /// @throws css::uno::RuntimeException |
403 | | /// @throws css::lang::IllegalArgumentException |
404 | | double Arg() const; |
405 | | inline double Abs() const; |
406 | | |
407 | | // following functions change the complex number itself to avoid unnecessary copy actions! |
408 | | /// @throws css::uno::RuntimeException |
409 | | /// @throws css::lang::IllegalArgumentException |
410 | | void Power( double fPower ); |
411 | | void Sqrt(); |
412 | | /// @throws css::uno::RuntimeException |
413 | | /// @throws css::lang::IllegalArgumentException |
414 | | void Sin(); |
415 | | /// @throws css::uno::RuntimeException |
416 | | /// @throws css::lang::IllegalArgumentException |
417 | | void Cos(); |
418 | | /// @throws css::uno::RuntimeException |
419 | | /// @throws css::lang::IllegalArgumentException |
420 | | void Div( const Complex& rDivisor ); |
421 | | void Exp(); |
422 | | inline void Conjugate(); |
423 | | /// @throws css::uno::RuntimeException |
424 | | /// @throws css::lang::IllegalArgumentException |
425 | | void Ln(); |
426 | | /// @throws css::uno::RuntimeException |
427 | | /// @throws css::lang::IllegalArgumentException |
428 | | void Log10(); |
429 | | /// @throws css::uno::RuntimeException |
430 | | /// @throws css::lang::IllegalArgumentException |
431 | | void Log2(); |
432 | | inline void Mult( double fFact ); |
433 | | inline void Mult( const Complex& rMult ); |
434 | | inline void Sub( const Complex& rMult ); |
435 | | inline void Add( const Complex& rAdd ); |
436 | | /// @throws css::uno::RuntimeException |
437 | | /// @throws css::lang::IllegalArgumentException |
438 | | void Tan(); |
439 | | /// @throws css::uno::RuntimeException |
440 | | /// @throws css::lang::IllegalArgumentException |
441 | | void Sec(); |
442 | | /// @throws css::uno::RuntimeException |
443 | | /// @throws css::lang::IllegalArgumentException |
444 | | void Csc(); |
445 | | /// @throws css::uno::RuntimeException |
446 | | /// @throws css::lang::IllegalArgumentException |
447 | | void Cot(); |
448 | | /// @throws css::uno::RuntimeException |
449 | | /// @throws css::lang::IllegalArgumentException |
450 | | void Sinh(); |
451 | | /// @throws css::uno::RuntimeException |
452 | | /// @throws css::lang::IllegalArgumentException |
453 | | void Cosh(); |
454 | | /// @throws css::uno::RuntimeException |
455 | | /// @throws css::lang::IllegalArgumentException |
456 | | void Sech(); |
457 | | /// @throws css::uno::RuntimeException |
458 | | /// @throws css::lang::IllegalArgumentException |
459 | | void Csch(); |
460 | | |
461 | | }; |
462 | | |
463 | | |
464 | | class ComplexList final |
465 | | { |
466 | | private: |
467 | | std::vector<Complex> maVector; |
468 | | public: |
469 | | ~ComplexList(); |
470 | | |
471 | | inline const Complex& Get( sal_uInt32 nIndex ) const; |
472 | | |
473 | | bool empty() const |
474 | 0 | { return maVector.empty(); } |
475 | | sal_uInt32 Count() const |
476 | 0 | { return maVector.size(); } |
477 | | |
478 | | inline void Append( Complex&& pNew ); |
479 | | /// @throws css::uno::RuntimeException |
480 | | /// @throws css::lang::IllegalArgumentException |
481 | | void Append( const css::uno::Sequence< css::uno::Sequence< OUString > >& rComplexNumList ); |
482 | | /// @throws css::uno::RuntimeException |
483 | | /// @throws css::lang::IllegalArgumentException |
484 | | void Append( const css::uno::Sequence< css::uno::Any >& aMultPars ); |
485 | | }; |
486 | | |
487 | | |
488 | | enum ConvertDataClass |
489 | | { |
490 | | CDC_Mass, CDC_Length, CDC_Time, CDC_Pressure, CDC_Force, CDC_Energy, CDC_Power, CDC_Magnetism, |
491 | | CDC_Temperature, CDC_Volume, CDC_Area, CDC_Speed, CDC_Information |
492 | | }; |
493 | | |
494 | | |
495 | | class ConvertData |
496 | | { |
497 | | protected: |
498 | | friend class ConvertDataList; |
499 | | double fConst; |
500 | | std::u16string_view aName; |
501 | | ConvertDataClass eClass; |
502 | | bool bPrefixSupport; |
503 | | public: |
504 | | ConvertData( |
505 | | std::u16string_view sUnitName, |
506 | | double fConvertConstant, |
507 | | ConvertDataClass eClass, |
508 | | bool bPrefSupport = false ); |
509 | | |
510 | | virtual ~ConvertData(); |
511 | | |
512 | | sal_Int16 GetMatchingLevel( const OUString& rRef ) const; |
513 | | // 0.0 = no equality |
514 | | // 1.0 = matches exact |
515 | | // rest = matches without an assumed prefix of one character |
516 | | // rest gives power for 10 represented by the prefix (e.g. 3 for k or -9 for n |
517 | | |
518 | | /// @throws css::uno::RuntimeException |
519 | | /// @throws css::lang::IllegalArgumentException |
520 | | virtual double Convert( double fVal, const ConvertData& rTo, |
521 | | sal_Int16 nMatchLevelFrom, sal_Int16 nMatchLevelTo ) const; |
522 | | |
523 | 15 | ConvertDataClass Class() const { return eClass; } |
524 | | }; |
525 | | |
526 | | class ConvertDataLinear final : public ConvertData |
527 | | { |
528 | | double fOffs; |
529 | | public: |
530 | | inline ConvertDataLinear( |
531 | | std::u16string_view sUnitName, |
532 | | double fConvertConstant, |
533 | | double fConvertOffset, |
534 | | ConvertDataClass eClass, |
535 | | bool bPrefSupport = false ); |
536 | | |
537 | | virtual ~ConvertDataLinear() override; |
538 | | |
539 | | virtual double Convert( double fVal, const ConvertData& rTo, |
540 | | sal_Int16 nMatchLevelFrom, sal_Int16 nMatchLevelTo ) const override; |
541 | | // for cases where f(x) = a + bx applies (e.g. Temperatures) |
542 | | |
543 | | // converts fVal from this unit to rFrom unit |
544 | | // throws exception if not from same class |
545 | | // this implementation is for proportional cases only |
546 | | double ConvertToBase( double fVal, sal_Int16 nMatchLevel ) const; |
547 | | double ConvertFromBase( double fVal, sal_Int16 nMatchLevel ) const; |
548 | | }; |
549 | | |
550 | | |
551 | | class ConvertDataList |
552 | | { |
553 | | private: |
554 | | std::vector<std::unique_ptr<ConvertData>> maVector; |
555 | | public: |
556 | | ConvertDataList(); |
557 | | ~ConvertDataList(); |
558 | | |
559 | | /// @throws css::uno::RuntimeException |
560 | | /// @throws css::lang::IllegalArgumentException |
561 | | double Convert( double fVal, const OUString& rFrom, const OUString& rTo ); |
562 | | }; |
563 | | |
564 | | |
565 | | inline bool IsLeapYear( sal_uInt16 n ) |
566 | 23 | { |
567 | 23 | return ( (( ( n % 4 ) == 0 ) && ( ( n % 100 ) != 0)) || ( ( n % 400 ) == 0 ) ); |
568 | 23 | } |
569 | | |
570 | | |
571 | | inline sal_Int32 GetDiffDate360( const css::uno::Reference< css::beans::XPropertySet >& xOpt, sal_Int32 nDate1, sal_Int32 nDate2, bool bUSAMethod ) |
572 | 0 | { |
573 | 0 | return GetDiffDate360( GetNullDate( xOpt ), nDate1, nDate2, bUSAMethod ); |
574 | 0 | } |
575 | | |
576 | | |
577 | | inline sal_Int16 GetDayOfWeek( sal_Int32 n ) |
578 | 78.8k | { // monday = 0, ..., sunday = 6 |
579 | 78.8k | return static_cast< sal_Int16 >( ( n - 1 ) % 7 ); |
580 | 78.8k | } |
581 | | |
582 | | |
583 | | inline double GetYearFrac( const css::uno::Reference< css::beans::XPropertySet >& xOpt, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) |
584 | 0 | { |
585 | 0 | return GetYearFrac( GetNullDate( xOpt ), nStartDate, nEndDate, nMode ); |
586 | 0 | } |
587 | | |
588 | | |
589 | | inline const TranslateId& FuncData::GetUINameID() const |
590 | 1.01k | { |
591 | 1.01k | return pUINameID; |
592 | 1.01k | } |
593 | | |
594 | | |
595 | | inline const TranslateId* FuncData::GetDescrID() const |
596 | 3.41k | { |
597 | 3.41k | return pDescrID; |
598 | 3.41k | } |
599 | | |
600 | | |
601 | | inline bool FuncData::IsDouble() const |
602 | 1.01k | { |
603 | 1.01k | return bDouble; |
604 | 1.01k | } |
605 | | |
606 | | |
607 | | inline const OUString& FuncData::GetSuffix() const |
608 | 100 | { |
609 | 100 | return aSuffix; |
610 | 100 | } |
611 | | |
612 | | |
613 | | inline bool FuncData::Is( std::u16string_view r ) const |
614 | 295k | { |
615 | 295k | return aIntName == r; |
616 | 295k | } |
617 | | |
618 | | |
619 | | inline const std::vector<OUString> & FuncData::GetCompNameList() const |
620 | 202 | { |
621 | 202 | return aCompList; |
622 | 202 | } |
623 | | |
624 | | |
625 | | inline FDCategory FuncData::GetCategory() const |
626 | 505 | { |
627 | 505 | return eCat; |
628 | 505 | } |
629 | | |
630 | | |
631 | | inline Complex::Complex( double fReal, double fImag, sal_Unicode cC ) : |
632 | 0 | c( cC ) |
633 | 0 | { |
634 | 0 | num = std::complex(fReal, fImag); |
635 | 0 | } |
636 | | |
637 | | |
638 | | inline double Complex::Real() const |
639 | 0 | { |
640 | 0 | return num.real(); |
641 | 0 | } |
642 | | |
643 | | |
644 | | inline double Complex::Imag() const |
645 | 0 | { |
646 | 0 | return num.imag(); |
647 | 0 | } |
648 | | |
649 | | |
650 | | inline double Complex::Abs() const |
651 | 0 | { |
652 | 0 | return std::abs(num); |
653 | 0 | } |
654 | | |
655 | | |
656 | | void Complex::Conjugate() |
657 | 0 | { |
658 | 0 | num = std::conj(num); |
659 | 0 | } |
660 | | |
661 | | |
662 | | inline void Complex::Mult( double f ) |
663 | 3 | { |
664 | 3 | num = num * f; |
665 | 3 | } |
666 | | |
667 | | |
668 | | inline void Complex::Mult( const Complex& rM ) |
669 | 0 | { |
670 | 0 | num = num * rM.num; |
671 | 0 | if( !c ) c = rM.c; |
672 | 0 | } |
673 | | |
674 | | |
675 | | inline void Complex::Sub( const Complex& rC ) |
676 | 0 | { |
677 | 0 | num = num - rC.num; |
678 | 0 | if( !c ) c = rC.c; |
679 | 0 | } |
680 | | |
681 | | |
682 | | inline void Complex::Add( const Complex& rAdd ) |
683 | 0 | { |
684 | 0 | num = num + rAdd.num; |
685 | 0 | if( !c ) c = rAdd.c; |
686 | 0 | } |
687 | | |
688 | | |
689 | | inline const Complex& ComplexList::Get( sal_uInt32 n ) const |
690 | 0 | { |
691 | 0 | return maVector[n]; |
692 | 0 | } |
693 | | |
694 | | |
695 | | inline void ComplexList::Append( Complex&& p ) |
696 | 0 | { |
697 | 0 | maVector.emplace_back(p); |
698 | 0 | } |
699 | | |
700 | | |
701 | | inline ConvertDataLinear::ConvertDataLinear( std::u16string_view sUnitName, double fC, double fO, ConvertDataClass e, |
702 | | bool bPrefSupport ) : |
703 | 8 | ConvertData( sUnitName, fC, e, bPrefSupport ), |
704 | 8 | fOffs( fO ) |
705 | 8 | { |
706 | 8 | } |
707 | | |
708 | | |
709 | | /// Helper class for date calculation for various financial functions |
710 | | class ScaDate |
711 | | { |
712 | | private: |
713 | | sal_uInt16 nOrigDay; /// is the day of the original date. |
714 | | sal_uInt16 nDay; /// is the calculated day depending on the current month/year. |
715 | | sal_uInt16 nMonth; /// is the current month (one-based). |
716 | | sal_uInt16 nYear; /// is the current year. |
717 | | bool bLastDayMode : 1; /// if true, recalculate nDay after every calculation. |
718 | | bool bLastDay : 1; /// is true, if original date was the last day in month. |
719 | | bool b30Days : 1; /// is true, if every month has 30 days in calculations. |
720 | | bool bUSMode : 1; /// is true, if the US method of 30-day-calculations is used. |
721 | | |
722 | | /// Calculates nDay from nOrigDay and current date. |
723 | | void setDay(); |
724 | | |
725 | | /// @return count of days in current month |
726 | | inline sal_uInt16 getDaysInMonth() const; |
727 | | /// @return count of days in given month |
728 | | inline sal_uInt16 getDaysInMonth( sal_uInt16 _nMon ) const; |
729 | | |
730 | | /// @ return count of days in the given month range |
731 | | sal_Int32 getDaysInMonthRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const; |
732 | | /// @ return count of days in the given year range |
733 | | sal_Int32 getDaysInYearRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const; |
734 | | |
735 | | /// Adds/subtracts the given count of years, does not adjust day. |
736 | | /// |
737 | | /// @throws css::lang::IllegalArgumentException |
738 | | void doAddYears( sal_Int32 nYearCount ); |
739 | | |
740 | | public: |
741 | | ScaDate(); |
742 | | /** @param nBase |
743 | | date handling mode (days in month / days in year): |
744 | | 0 = 30 days / 360 days (US NASD) |
745 | | 1 = exact / exact |
746 | | 2 = exact / 360 |
747 | | 3 = exact / 365 |
748 | | 4 = 30 days / 360 days (Europe) |
749 | | 5 = exact / exact (no last day adjustment) */ |
750 | | ScaDate( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nBase ); |
751 | | ScaDate( const ScaDate& rCopy ); |
752 | | ScaDate& operator=( const ScaDate& rCopy ); |
753 | | |
754 | | /// @return the current month. |
755 | 6 | sal_uInt16 getMonth() const { return nMonth; }; |
756 | | /// @return the current year. |
757 | 9 | sal_uInt16 getYear() const { return nYear; }; |
758 | | |
759 | | /// adds/subtracts the given count of months, adjusts day |
760 | | /// |
761 | | /// @throws css::lang::IllegalArgumentException |
762 | | void addMonths( sal_Int32 nMonthCount ); |
763 | | |
764 | | /// sets the given year, adjusts day |
765 | | inline void setYear( sal_uInt16 nNewYear ); |
766 | | /// adds/subtracts the given count of years, adjusts day |
767 | | /// |
768 | | /// @throws css::lang::IllegalArgumentException |
769 | | inline void addYears( sal_Int32 nYearCount ); |
770 | | |
771 | | /// @return the internal number of the current date |
772 | | sal_Int32 getDate( sal_Int32 nNullDate ) const; |
773 | | /// @return the number of days between the two dates |
774 | | /// |
775 | | /// @throws css::lang::IllegalArgumentException |
776 | | static sal_Int32 getDiff( const ScaDate& rFrom, const ScaDate& rTo ); |
777 | | |
778 | | bool operator<( const ScaDate& rCmp ) const; |
779 | 0 | bool operator<=( const ScaDate& rCmp ) const { return !(rCmp < *this); } |
780 | 3 | bool operator>( const ScaDate& rCmp ) const { return rCmp < *this; } |
781 | 0 | bool operator>=( const ScaDate& rCmp ) const { return !(*this < rCmp); } |
782 | | }; |
783 | | |
784 | | inline sal_uInt16 ScaDate::getDaysInMonth() const |
785 | 0 | { |
786 | 0 | return getDaysInMonth( nMonth ); |
787 | 0 | } |
788 | | |
789 | | inline sal_uInt16 ScaDate::getDaysInMonth( sal_uInt16 _nMon ) const |
790 | 0 | { |
791 | 0 | return b30Days ? 30 : DaysInMonth( _nMon, nYear ); |
792 | 0 | } |
793 | | |
794 | | inline void ScaDate::setYear( sal_uInt16 nNewYear ) |
795 | 3 | { |
796 | 3 | nYear = nNewYear; |
797 | 3 | setDay(); |
798 | 3 | } |
799 | | |
800 | | inline void ScaDate::addYears( sal_Int32 nYearCount ) |
801 | 0 | { |
802 | 0 | doAddYears( nYearCount ); |
803 | 0 | setDay(); |
804 | 0 | } |
805 | | |
806 | | |
807 | | /// Helper class for Any->double conversion, using the current locale |
808 | | class ScaAnyConverter |
809 | | { |
810 | | private: |
811 | | css::uno::Reference< css::util::XNumberFormatter2 > xFormatter; |
812 | | sal_Int32 nDefaultFormat; |
813 | | bool bHasValidFormat; |
814 | | |
815 | | /** Converts a string to double using the number formatter. If the formatter is not |
816 | | valid, ::rtl::math::stringToDouble() with english separators will be used. |
817 | | @throws css::lang::IllegalArgumentException |
818 | | on strings not representing any double value. |
819 | | @return the converted double value. */ |
820 | | double convertToDouble( |
821 | | const OUString& rString ) const; |
822 | | |
823 | | public: |
824 | | explicit ScaAnyConverter( |
825 | | const css::uno::Reference< css::uno::XComponentContext >& xContext ); |
826 | | ~ScaAnyConverter(); |
827 | | |
828 | | /// Initializing with the current locale |
829 | | /// |
830 | | /// @throws css::uno::RuntimeException |
831 | | void init( |
832 | | const css::uno::Reference< css::beans::XPropertySet >& xPropSet ); |
833 | | |
834 | | /** Converts an Any to double (without initialization). |
835 | | The Any can be empty or contain a double or string. |
836 | | @throws css::lang::IllegalArgumentException |
837 | | on other Any types or on invalid strings. |
838 | | @return true if the Any contains a double or a non-empty valid string, |
839 | | false if the Any is empty or the string is empty */ |
840 | | bool getDouble( |
841 | | double& rfResult, |
842 | | const css::uno::Any& rAny ) const; |
843 | | |
844 | | /** Converts an Any to double (with initialization). |
845 | | The Any can be empty or contain a double or string. |
846 | | @throws css::lang::IllegalArgumentException |
847 | | on other Any types or on invalid strings. |
848 | | @return true if the Any contains a double or a non-empty valid string, |
849 | | false if the Any is empty or the string is empty */ |
850 | | bool getDouble( |
851 | | double& rfResult, |
852 | | const css::uno::Reference< css::beans::XPropertySet >& xPropSet, |
853 | | const css::uno::Any& rAny ); |
854 | | |
855 | | /** Converts an Any to double (with initialization). |
856 | | The Any can be empty or contain a double or string. |
857 | | @throws css::lang::IllegalArgumentException |
858 | | on other Any types or on invalid strings. |
859 | | @return the value of the double or string or fDefault if the Any or string is empty */ |
860 | | double getDouble( |
861 | | const css::uno::Reference< css::beans::XPropertySet >& xPropSet, |
862 | | const css::uno::Any& rAny, |
863 | | double fDefault ); |
864 | | |
865 | | /** Converts an Any to sal_Int32 (with initialization). |
866 | | The Any can be empty or contain a double or string. |
867 | | @throws css::lang::IllegalArgumentException |
868 | | on other Any types or on invalid values or strings. |
869 | | @return true if the Any contains a double or a non-empty valid string, |
870 | | false if the Any is empty or the string is empty */ |
871 | | bool getInt32( |
872 | | sal_Int32& rnResult, |
873 | | const css::uno::Reference< css::beans::XPropertySet >& xPropSet, |
874 | | const css::uno::Any& rAny ); |
875 | | |
876 | | /** Converts an Any to sal_Int32 (with initialization). |
877 | | The Any can be empty or contain a double or string. |
878 | | @throws css::lang::IllegalArgumentException |
879 | | on other Any types or on invalid values or strings. |
880 | | @return the truncated value of the double or string or nDefault if the Any or string is empty */ |
881 | | sal_Int32 getInt32( |
882 | | const css::uno::Reference< css::beans::XPropertySet >& xPropSet, |
883 | | const css::uno::Any& rAny, |
884 | | sal_Int32 nDefault ); |
885 | | }; |
886 | | |
887 | | } |
888 | | |
889 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |