summaryrefslogtreecommitdiff
path: root/sc/inc/formulagroup.hxx
blob: f0dcb4888a7278cfe79c716b2a0a4a189f84031e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef INCLUDED_SC_INC_FORMULAGROUP_HXX
#define INCLUDED_SC_INC_FORMULAGROUP_HXX

#include <config_features.h>

#include "address.hxx"
#include "calcconfig.hxx"
#include "types.hxx"
#include "stlalgorithm.hxx"

#if HAVE_FEATURE_OPENCL
#include <opencl/platforminfo.hxx>
#endif

#include <memory>
#include <unordered_map>
#include <vector>

class ScDocument;
class ScTokenArray;
class ScFormulaCell;

namespace sc {

struct FormulaGroupEntry
{
    union
    {
        ScFormulaCell* mpCell;   // non-shared formula cell
        ScFormulaCell** mpCells; // pointer to the top formula cell in a shared group.
    };

    size_t mnRow;
    size_t mnLength;
    bool mbShared;

    FormulaGroupEntry( ScFormulaCell** pCells, size_t nRow, size_t nLength );

    FormulaGroupEntry( ScFormulaCell* pCell, size_t nRow );
};

// Despite the name, this is actually a cache of cell values, used by OpenCL
// code ... I think. And obviously it's not really a struct either.
struct FormulaGroupContext
{
    typedef AlignedAllocator<double,256> DoubleAllocType;
    typedef std::vector<double, DoubleAllocType> NumArrayType;
    typedef std::vector<rtl_uString*> StrArrayType;
    typedef std::vector<std::unique_ptr<NumArrayType>> NumArrayStoreType;
    typedef std::vector<std::unique_ptr<StrArrayType>> StrArrayStoreType;

    struct ColKey
    {
        SCTAB mnTab;
        SCCOL mnCol;

        struct Hash
        {
            size_t operator() ( const ColKey& rKey ) const;
        };

        ColKey( SCTAB nTab, SCCOL nCol );

        bool operator== ( const ColKey& r ) const;
    };

    struct ColArray
    {
        NumArrayType* mpNumArray;
        StrArrayType* mpStrArray;
        size_t mnSize;

        ColArray( NumArrayType* pNumArray, StrArrayType* pStrArray );
    };

    typedef std::unordered_map<ColKey, ColArray, ColKey::Hash> ColArraysType;

    NumArrayStoreType m_NumArrays; /// manage life cycle of numeric arrays.
    StrArrayStoreType m_StrArrays; /// manage life cycle of string arrays.

    ColArraysType maColArrays; /// keep track of longest array for each column.

    ColArray* getCachedColArray( SCTAB nTab, SCCOL nCol, size_t nSize );

    ColArray* setCachedColArray(
        SCTAB nTab, SCCOL nCol, NumArrayType* pNumArray, StrArrayType* pStrArray );

    void ensureStrArray( ColArray& rColArray, size_t nArrayLen );
    void ensureNumArray( ColArray& rColArray, size_t nArrayLen );

    FormulaGroupContext();
    FormulaGroupContext(const FormulaGroupContext&) = delete;
    const FormulaGroupContext& operator=(const FormulaGroupContext&) = delete;
    ~FormulaGroupContext();
};

/**
 * Abstract base class for a "compiled" formula
 */
class SC_DLLPUBLIC CompiledFormula
{
public:
    CompiledFormula();
    virtual ~CompiledFormula();
};

/**
 * Abstract base class for vectorised formula group interpreters,
 * plus a global instance factory.
 */
class SC_DLLPUBLIC FormulaGroupInterpreter
{
    static FormulaGroupInterpreter *msInstance;

protected:
    ScCalcConfig maCalcConfig;

    FormulaGroupInterpreter() {}
    virtual ~FormulaGroupInterpreter() {}

    /// Merge global and document specific settings.
    void MergeCalcConfig(const ScDocument& rDoc);

public:
    static FormulaGroupInterpreter *getStatic();
#if HAVE_FEATURE_OPENCL
    static void fillOpenCLInfo(std::vector<OpenCLPlatformInfo>& rPlatforms);
    static bool switchOpenCLDevice(const OUString& rDeviceId, bool bAutoSelect, bool bForceEvaluation = false);
    // This is intended to be called from opencl-test.cxx only
    static void enableOpenCL_UnitTestsOnly();
    static void disableOpenCL_UnitTestsOnly();
    static void getOpenCLDeviceInfo(sal_Int32& rDeviceId, sal_Int32& rPlatformId);
#endif
    virtual ScMatrixRef inverseMatrix(const ScMatrix& rMat) = 0;
    virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos, ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) = 0;
};

/// Inherit from this for alternate formula group calculation approaches.
class SC_DLLPUBLIC FormulaGroupInterpreterSoftware : public FormulaGroupInterpreter
{
public:
    FormulaGroupInterpreterSoftware();

    virtual ScMatrixRef inverseMatrix(const ScMatrix& rMat) override;
    virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos, ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) override;
};

}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */