Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */