1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
25 #include <formula/opcode.hxx>
26 #include "refdata.hxx"
28 #include <formula/token.hxx>
29 #include "calcmacros.hxx"
32 // Matrix token constants.
33 #define MATRIX_TOKEN_HAS_RANGE 1
39 typedef ::std::vector
< ScComplexRefData
> ScRefList
;
41 #if DEBUG_FORMULA_COMPILER
42 void DumpToken(formula::FormulaToken
const & rToken
);
45 /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge
46 ranges as needed for ocRange.
48 The formula's position, used to calculate absolute positions from
50 @param bReuseDoubleRef
51 If true, a DoubleRef token is reused if passed as rTok1 or rTok2,
52 else a new DoubleRef token is created and returned.
54 A reused or new'ed ScDoubleRefToken, or a NULL TokenRef if rTok1 or
55 rTok2 are not of sv(Single|Double)Ref
57 formula::FormulaTokenRef
extendRangeReference( ScSheetLimits
& rLimits
, formula::FormulaToken
& rTok1
, formula::FormulaToken
& rTok2
, const ScAddress
& rPos
, bool bReuseDoubleRef
);
59 class ScSingleRefToken final
: public formula::FormulaToken
62 ScSheetLimits
& mrSheetLimits
; // don't use rtl::Reference to avoid ref-counting traffic
63 ScSingleRefData aSingleRef
;
65 ScSingleRefToken( ScSheetLimits
& rLimits
, const ScSingleRefData
& r
, OpCode e
= ocPush
) :
66 FormulaToken( formula::svSingleRef
, e
), mrSheetLimits(rLimits
), aSingleRef( r
) {}
67 virtual const ScSingleRefData
* GetSingleRef() const override
;
68 virtual ScSingleRefData
* GetSingleRef() override
;
69 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const override
;
70 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
71 virtual FormulaToken
* Clone() const override
{ return new ScSingleRefToken(*this); }
74 class ScDoubleRefToken final
: public formula::FormulaToken
77 ScSheetLimits
& mrSheetLimits
; // don't use rtl::Reference to avoid ref-counting traffic
78 ScComplexRefData aDoubleRef
;
80 ScDoubleRefToken( ScSheetLimits
& rLimits
, const ScComplexRefData
& r
, OpCode e
= ocPush
) :
81 FormulaToken( formula::svDoubleRef
, e
), mrSheetLimits(rLimits
), aDoubleRef( r
) {}
82 virtual const ScSingleRefData
* GetSingleRef() const override
;
83 virtual ScSingleRefData
* GetSingleRef() override
;
84 virtual const ScComplexRefData
* GetDoubleRef() const override
;
85 virtual ScComplexRefData
* GetDoubleRef() override
;
86 virtual const ScSingleRefData
* GetSingleRef2() const override
;
87 virtual ScSingleRefData
* GetSingleRef2() override
;
88 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const override
;
89 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
90 virtual FormulaToken
* Clone() const override
{ return new ScDoubleRefToken(*this); }
93 class ScMatrixToken final
: public formula::FormulaToken
98 ScMatrixToken( ScMatrixRef p
);
99 ScMatrixToken( const ScMatrixToken
& );
101 virtual const ScMatrix
* GetMatrix() const override
;
102 virtual ScMatrix
* GetMatrix() override
;
103 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
104 virtual FormulaToken
* Clone() const override
{ return new ScMatrixToken(*this); }
108 * Token storing matrix that represents values in sheet range. It stores
109 * both the values in matrix form, and the range address the matrix
112 class ScMatrixRangeToken final
: public formula::FormulaToken
114 ScMatrixRef mpMatrix
;
115 ScComplexRefData maRef
;
117 ScMatrixRangeToken( const sc::RangeMatrix
& rMat
);
118 ScMatrixRangeToken( const ScMatrixRangeToken
& );
120 virtual sal_uInt8
GetByte() const override
;
121 virtual const ScMatrix
* GetMatrix() const override
;
122 virtual ScMatrix
* GetMatrix() override
;
123 virtual const ScComplexRefData
* GetDoubleRef() const override
;
124 virtual ScComplexRefData
* GetDoubleRef() override
;
125 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
126 virtual FormulaToken
* Clone() const override
;
129 class ScExternalSingleRefToken final
: public formula::FormulaToken
132 svl::SharedString maTabName
;
133 ScSingleRefData maSingleRef
;
136 ScExternalSingleRefToken( sal_uInt16 nFileId
, svl::SharedString aTabName
, const ScSingleRefData
& r
);
137 ScExternalSingleRefToken() = delete;
138 virtual ~ScExternalSingleRefToken() override
;
140 ScExternalSingleRefToken(ScExternalSingleRefToken
const &) = default;
141 ScExternalSingleRefToken(ScExternalSingleRefToken
&&) = default;
142 ScExternalSingleRefToken
& operator =(ScExternalSingleRefToken
const &) = delete; // due to FormulaToken
143 ScExternalSingleRefToken
& operator =(ScExternalSingleRefToken
&&) = delete; // due to FormulaToken
145 virtual sal_uInt16
GetIndex() const override
;
146 virtual const svl::SharedString
& GetString() const override
;
147 virtual const ScSingleRefData
* GetSingleRef() const override
;
148 virtual ScSingleRefData
* GetSingleRef() override
;
149 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
150 virtual FormulaToken
* Clone() const override
{ return new ScExternalSingleRefToken(*this); }
153 class ScExternalDoubleRefToken final
: public formula::FormulaToken
156 svl::SharedString maTabName
; // name of the first sheet
157 ScComplexRefData maDoubleRef
;
160 ScExternalDoubleRefToken() = delete;
161 ScExternalDoubleRefToken( sal_uInt16 nFileId
, svl::SharedString aTabName
, const ScComplexRefData
& r
);
162 virtual ~ScExternalDoubleRefToken() override
;
164 ScExternalDoubleRefToken(ScExternalDoubleRefToken
const &) = default;
165 ScExternalDoubleRefToken(ScExternalDoubleRefToken
&&) = default;
166 ScExternalDoubleRefToken
& operator =(ScExternalDoubleRefToken
const &) = delete; // due to FormulaToken
167 ScExternalDoubleRefToken
& operator =(ScExternalDoubleRefToken
&&) = delete; // due to FormulaToken
169 virtual sal_uInt16
GetIndex() const override
;
170 virtual const svl::SharedString
& GetString() const override
;
171 virtual const ScSingleRefData
* GetSingleRef() const override
;
172 virtual ScSingleRefData
* GetSingleRef() override
;
173 virtual const ScSingleRefData
* GetSingleRef2() const override
;
174 virtual ScSingleRefData
* GetSingleRef2() override
;
175 virtual const ScComplexRefData
* GetDoubleRef() const override
;
176 virtual ScComplexRefData
* GetDoubleRef() override
;
177 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
178 virtual FormulaToken
* Clone() const override
{ return new ScExternalDoubleRefToken(*this); }
181 class ScExternalNameToken final
: public formula::FormulaToken
184 svl::SharedString maName
;
187 ScExternalNameToken() = delete;
188 ScExternalNameToken( sal_uInt16 nFileId
, svl::SharedString aName
);
189 virtual ~ScExternalNameToken() override
;
191 ScExternalNameToken(ScExternalNameToken
const &) = default;
192 ScExternalNameToken(ScExternalNameToken
&&) = default;
193 ScExternalNameToken
& operator =(ScExternalNameToken
const &) = delete; // due to FormulaToken
194 ScExternalNameToken
& operator =(ScExternalNameToken
&&) = delete; // due to FormulaToken
196 virtual sal_uInt16
GetIndex() const override
;
197 virtual const svl::SharedString
& GetString() const override
;
198 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
199 virtual FormulaToken
* Clone() const override
{ return new ScExternalNameToken(*this); }
202 /** Special token to remember details of ocTableRef "structured references". */
203 class ScTableRefToken final
: public formula::FormulaToken
215 HEADERS_DATA
= HEADERS
| DATA
,
216 DATA_TOTALS
= DATA
| TOTALS
219 ScTableRefToken() = delete;
220 ScTableRefToken( sal_uInt16 nIndex
, Item eItem
);
221 ScTableRefToken( const ScTableRefToken
& r
);
222 virtual ~ScTableRefToken() override
;
224 virtual sal_uInt16
GetIndex() const override
;
225 virtual void SetIndex( sal_uInt16 n
) override
;
226 virtual sal_Int16
GetSheet() const override
;
227 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
228 virtual FormulaToken
* Clone() const override
{ return new ScTableRefToken(*this); }
230 Item
GetItem() const;
231 void AddItem( Item
);
232 void SetAreaRefRPN( formula::FormulaToken
* pToken
);
233 formula::FormulaToken
* GetAreaRefRPN() const;
237 formula::FormulaTokenRef mxAreaRefRPN
; ///< resulting RPN area
238 sal_uInt16 mnIndex
; ///< index into table / database range collection
242 // Only created from within the interpreter, no conversion from ScRawToken,
243 // never added to ScTokenArray!
244 class ScJumpMatrixToken final
: public formula::FormulaToken
247 std::shared_ptr
<ScJumpMatrix
> mpJumpMatrix
;
249 ScJumpMatrixToken( std::shared_ptr
<ScJumpMatrix
> p
);
250 ScJumpMatrixToken( const ScJumpMatrixToken
& );
251 virtual ~ScJumpMatrixToken() override
;
252 virtual ScJumpMatrix
* GetJumpMatrix() const override
;
253 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
254 virtual FormulaToken
* Clone() const override
{ return new ScJumpMatrixToken(*this); }
257 // Only created from within the interpreter, no conversion from ScRawToken,
258 // never added to ScTokenArray!
259 class ScRefListToken final
: public formula::FormulaToken
263 bool mbArrayResult
; // whether RefList is an array result
266 FormulaToken( formula::svRefList
), mbArrayResult(false) {}
267 explicit ScRefListToken( bool bArrayResult
) :
268 FormulaToken( formula::svRefList
), mbArrayResult( bArrayResult
) {}
269 bool IsArrayResult() const;
270 virtual const ScRefList
* GetRefList() const override
;
271 virtual ScRefList
* GetRefList() override
;
272 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
273 virtual FormulaToken
* Clone() const override
{ return new ScRefListToken(*this); }
276 class ScEmptyCellToken final
: public formula::FormulaToken
279 bool bDisplayedAsString
:1;
281 explicit ScEmptyCellToken( bool bInheritedP
, bool bDisplayAsString
) :
282 FormulaToken( formula::svEmptyCell
),
283 bInherited( bInheritedP
),
284 bDisplayedAsString( bDisplayAsString
) {}
285 bool IsInherited() const { return bInherited
; }
286 bool IsDisplayedAsString() const { return bDisplayedAsString
; }
287 virtual double GetDouble() const override
;
288 virtual const svl::SharedString
& GetString() const override
;
289 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
290 virtual FormulaToken
* Clone() const override
{ return new ScEmptyCellToken(*this); }
293 /** Transports the result from the interpreter to the formula cell. */
294 class ScMatrixCellResultToken
: public formula::FormulaToken
296 // No non-const access implemented, silence down unxsols4 complaining about
297 // the public GetMatrix() hiding the one from FormulaToken.
298 virtual ScMatrix
* GetMatrix() override
;
301 ScConstMatrixRef xMatrix
;
302 formula::FormulaConstTokenRef xUpperLeft
;
304 ScMatrixCellResultToken( ScConstMatrixRef pMat
, const formula::FormulaToken
* pUL
);
305 ScMatrixCellResultToken( const ScMatrixCellResultToken
& );
306 virtual ~ScMatrixCellResultToken() override
;
307 virtual double GetDouble() const override
;
308 virtual const svl::SharedString
& GetString() const override
;
309 virtual const ScMatrix
* GetMatrix() const override
;
310 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
311 virtual FormulaToken
* Clone() const override
;
312 formula::StackVar
GetUpperLeftType() const
315 xUpperLeft
->GetType() :
318 const formula::FormulaConstTokenRef
& GetUpperLeftToken() const { return xUpperLeft
; }
319 void Assign( const ScMatrixCellResultToken
& r
);
322 /** Stores the matrix result at the formula cell, additionally the range the
323 matrix formula occupies. */
324 class ScMatrixFormulaCellToken final
: public ScMatrixCellResultToken
330 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
, const ScConstMatrixRef
& pMat
, const formula::FormulaToken
* pUL
);
331 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
);
332 ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken
& r
);
333 virtual ~ScMatrixFormulaCellToken() override
;
335 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
336 virtual FormulaToken
* Clone() const override
{ return new ScMatrixFormulaCellToken(*this); }
337 void SetMatColsRows( SCCOL nC
, SCROW nR
)
342 void GetMatColsRows( SCCOL
& nC
, SCROW
& nR
) const
347 SCCOL
GetMatCols() const { return nCols
; }
348 SCROW
GetMatRows() const { return nRows
; }
350 /** Assign matrix result, keep matrix formula
352 void Assign( const ScMatrixCellResultToken
& r
);
354 /** Assign any result, keep matrix formula
355 dimension. If token is of type
356 ScMatrixCellResultToken uses the
357 appropriate Assign() call, other tokens
358 are assigned to xUpperLeft and xMatrix will
360 void Assign( const formula::FormulaToken
& r
);
362 /** Modify xUpperLeft if formula::svDouble, or create
363 new formula::FormulaDoubleToken if not set yet. Does
364 nothing if xUpperLeft is of different type! */
365 void SetUpperLeftDouble( double f
);
367 /** Reset matrix and upper left, keep matrix
368 formula dimension. */
373 /** xUpperLeft is modifiable through SetUpperLeftDouble(), so clone it
374 whenever an svDouble token is assigned to. */
375 void CloneUpperLeftIfNecessary();
378 class ScHybridCellToken final
: public formula::FormulaToken
382 svl::SharedString maString
;
384 bool mbEmptyDisplayedAsString
;
387 double f
, const svl::SharedString
& rStr
, OUString aFormula
, bool bEmptyDisplayedAsString
);
389 const OUString
& GetFormula() const { return maFormula
; }
390 bool IsEmptyDisplayedAsString() const { return mbEmptyDisplayedAsString
; }
391 virtual double GetDouble() const override
;
393 virtual const svl::SharedString
& GetString() const override
;
394 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
395 virtual FormulaToken
* Clone() const override
{ return new ScHybridCellToken(*this); }
398 // Simplify argument passing to RefUpdate methods with ScSingleRefToken or
400 class SingleDoubleRefModifier
402 ScComplexRefData aDub
;
404 ScComplexRefData
* pD
;
406 SingleDoubleRefModifier( const SingleDoubleRefModifier
& ) = delete;
407 SingleDoubleRefModifier
& operator=( const SingleDoubleRefModifier
& ) = delete;
410 SingleDoubleRefModifier( formula::FormulaToken
& rT
)
412 formula::StackVar eType
= rT
.GetType();
413 if ( eType
== formula::svSingleRef
|| eType
== formula::svExternalSingleRef
)
415 pS
= rT
.GetSingleRef();
416 aDub
.Ref1
= aDub
.Ref2
= *pS
;
422 pD
= rT
.GetDoubleRef();
423 // coverity[uninit_member] - aDub intentionally not initialized, unnecessary because unused.
426 SingleDoubleRefModifier( ScSingleRefData
& rS
)
429 aDub
.Ref1
= aDub
.Ref2
= *pS
;
432 ~SingleDoubleRefModifier()
437 ScComplexRefData
& Ref() { return *pD
; }
440 class SingleDoubleRefProvider
444 const ScSingleRefData
& Ref1
;
445 const ScSingleRefData
& Ref2
;
447 SingleDoubleRefProvider( const formula::FormulaToken
& r
)
448 : Ref1( *r
.GetSingleRef() ),
449 Ref2( (r
.GetType() == formula::svDoubleRef
||
450 r
.GetType() == formula::svExternalDoubleRef
) ?
451 r
.GetDoubleRef()->Ref2
: Ref1
)
455 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */